# perf record **`perf record` samples the program at a fixed event rate** and captures the current instruction pointer and call stack at each sample. This produces a data file (`perf.data`) that can be analyzed later to see where in the code the CPU was spending time. ```bash perf record ./program # sample every 4000 cycles (default) perf record -g ./program # with call graphs perf record --call-graph dwarf ./program # with DWARF unwinding for accuracy ``` By default, perf samples every 4000 CPU cycles—a good default for most programs. Each sample records the instruction pointer (where the CPU was) and the call stack (how it got there). The samples are written to `perf.data` in the current directory. **Sampling rate** controls how frequently samples are taken: ```bash perf record -F 99 ./program # sample 99 times per second perf record -F 1000 ./program # sample 1000 times per second (higher overhead) ``` Higher frequencies give more samples and better statistical coverage but add more overhead. `-F 99` (99 Hz) is typical for profiling HPC code; it adds minimal overhead. **Call graphs** show the function call chain that led to each sample. Without `-g`, perf only records the leaf instruction. With `-g`, it records the full call stack: ```bash perf record -g --call-graph dwarf ./program # DWARF-based unwinding (accurate) perf record -g --call-graph fp ./program # frame-pointer unwinding (fast, requires -fno-omit-frame-pointer) ``` `--call-graph dwarf` uses DWARF debug info to unwind the stack; this works on any optimized binary compiled with `-g`. `--call-graph fp` uses frame pointers in the stack frame; this is faster but requires the binary to be compiled with `-fno-omit-frame-pointer` (not standard on optimized code). DWARF is recommended for profiling optimized binaries because it doesn't require special compilation flags and is more reliable. **Filtering events:** ```bash perf record -e cycles ./program # only count cycle samples perf record -e L1-dcache-load-misses ./program # sample on cache misses ``` By default, perf samples on cycles. You can change the event to sample on cache misses, branch mispredictions, or other events. Sampling on rare events (like cache misses) gives fewer samples but focuses on specific phenomena. **Data file management:** ```bash perf record -o mydata.data ./program # save to custom file (default: perf.data) perf record -a ./program # system-wide recording (all CPUs) ``` Without `-o`, perf writes to `perf.data` in the current directory, overwriting any existing data. Use `-o` to save multiple profiles separately.