Project 23: Performance Profiler

Project 23: Performance Profiler

Build a sampling profiler that periodically interrupts a program, records where it is, and reports the hottest functions and call stacks.

Quick Reference

Attribute Value
Difficulty Advanced
Time Estimate 1-2 weeks
Language C (Alternatives: C++, Rust)
Prerequisites Comfort with signals, stacks, and basic asm concepts
Key Topics Statistical profiling, timer signals, instruction pointers, unwinding
CS:APP Chapters 5 (performance), 8 (signals), 3 (machine-level context)

1. Learning Objectives

By completing this project, you will:

  1. Implement timer-based sampling (SIGPROF/ITIMER_PROF)
  2. Capture instruction pointers and aggregate them into a meaningful report
  3. Symbolize addresses back to function names (at least at the โ€œbest effortโ€ level)
  4. Explain what profilers can/canโ€™t tell you (bias, sampling error, Heisenberg effects)

2. Project Specification

Build profiler:

  • ./profiler --hz=1000 -- ./target arg1 arg2
  • Starts the target under profiling, samples periodically, then prints a report
  • Report includes: total samples, top N symbols, optional call-chain buckets

3. Architecture

  • Sampler: installs sigaction(SIGPROF, SA_SIGINFO) + setitimer
  • Collector: writes minimal samples to a lock-free-ish buffer (or per-thread buffers)
  • Symbolizer: post-processes samples with dladdr and/or addr2line (optional)

4. Testing Strategy

  • Profile synthetic workloads with known hot loops.
  • Verify sampling frequency and overhead (compare runtime with/without profiler).
  • Cross-check with perf/dtrace/Instruments if available.

5. Extensions

  • Export a folded-stack format for flamegraphs.
  • Add per-thread sampling and reports.
  • Add hardware-counter-based sampling (Linux perf_event_open).

6. Reference Reading

  • CS:APP 3e โ€” performance chapters (locality/measurement)
  • man setitimer, man sigaction, man dladdr