# Valgrind callgrind **callgrind** is a profiling tool built on Valgrind's instrumentation engine. Unlike [[perf]], which samples at fixed intervals, callgrind counts instructions deterministically—every instruction is counted. This gives reproducible results even for very short-running programs. ```bash valgrind --tool=callgrind ./program callgrind_annotate callgrind.out.12345 ``` `perf record` is fast but requires many samples to be statistically accurate. callgrind is slower but deterministic—perfect for analyzing short-lived test cases or programs where sampling might miss small but important functions. **Generating profiles:** ```bash valgrind --tool=callgrind --dump-instr=yes ./program # detailed instruction counts callgrind_annotate callgrind.out.PID ``` By default, callgrind records per-function instruction counts and call graphs. `--dump-instr=yes` adds per-instruction counts (larger data file, more detail). **Output:** `callgrind_annotate` displays the call graph sorted by instruction count. Each line shows a function, number of instructions executed, and number of times it was called: ``` Ir Calls Fn name 1,234,567 5,000 main 1,000,000 1,000 process 500,000 1,000 compute_kernel 250,000 1,000 matrix_multiply ``` "Ir" is instruction references (instructions executed). This shows main executed 1.2M instructions and called process 5000 times. **Advantages over perf:** 1. Deterministic: same results every run (no sampling noise) 2. Complete: captures every instruction, never misses small functions 3. Reliable: short programs that don't generate enough samples under perf are profiled accurately **Disadvantages:** 1. Slow: 10-50x overhead from instrumentation 2. Not real-time: can't profile production workloads 3. Memory-heavy: large programs produce gigabyte-sized profile files **Use cases:** Test suite profiling, understanding performance of short algorithms, verifying that optimizations are effective (deterministic comparisons), profiling on systems where perf isn't available. **Comparing callgrind profiles:** ```bash valgrind --tool=callgrind --outfile=profile1.out ./program_v1 valgrind --tool=callgrind --outfile=profile2.out ./program_v2 callgrind_annotate profile1.out profile2.out ``` This compares two profiles side-by-side, showing which functions changed performance.