Appearance
perf record —— 性能采样
更新时间:2026-08-06
perf record 采集程序的性能采样数据,生成 perf.data 文件,供 perf report、perf annotate、火焰图等工具分析。
关联:perf-report.md(数据分析)、perf-flamegraph.md(火焰图)、perf-internals.md(原理)
一、perf record 能回答什么问题
| 问题 | 选项 | 后续分析 |
|---|---|---|
| 哪个函数占用 CPU 最多? | 默认采样 cycles | perf report |
| 完整的调用链是怎样的? | -g(记录调用栈) | perf report -g + 火焰图 |
| CPU 前/后端哪个是瓶颈? | -e stalled-cycles-frontend,stalled-cycles-backend | perf report |
| 采样频率不够或太多? | -F 99 / -c 100000 | — |
| 需要最精确的指令地址? | -e cycles:pp | PEBS/LBR 精确采样 |
二、基本使用
2.1 最简采样
bash
# 采集程序运行的性能数据(默认事件:cycles,采样频率 4000 Hz)
perf record ./your_program
# 分析数据
perf report2.2 记录调用栈
bash
# -g: 记录调用栈(call graph)
perf record -g ./your_program采样时每个采样点不仅记录当前指令地址,还回溯整个函数调用链。这是生成火焰图的前提。
2.3 采样运行中的进程
bash
# 监控 PID 为 12345 的进程,持续 30 秒
perf record -p 12345 -- sleep 30
# 监控全系统,持续 10 秒
perf record -a -g -- sleep 10务必带时长控制:不加
-- sleep N或Ctrl+C会无限录制,perf.data可能迅速增长到 GB 级别。
三、常用选项
| 选项 | 含义 | 典型值 |
|---|---|---|
-F <Hz> | 采样频率(每秒采样次数) | -F 99(火焰图推荐),-F 999(高精度) |
-c <count> | 采样周期(每 N 个事件采一次) | -c 100000(每 10 万 cycle 采一次) |
-g | 记录调用栈 | — |
--call-graph <mode> | 调用栈回溯方式 | fp(默认)、dwarf、lbr |
-e <event> | 采样事件 | cycles(默认)、instructions、cache-misses 等 |
-a | 全系统采样 | — |
-p <pid> | 仅采样指定进程 | — |
-t <tid> | 仅采样指定线程 | — |
-C <cpu> | 仅采样指定 CPU 核 | -C 0,1 |
-o <file> | 输出文件 | -o my_perf.data |
-m <pages> | mmap 缓冲区大小 | -m 256(增大可减少数据丢失) |
--switch-events | 记录上下文切换事件 | 结合 perf report --tasks |
--timestamp | 记录时间戳 | 用于时间线分析 |
四、采样频率 vs 采样周期
-F(频率模式)
bash
# 每秒采样 99 次(Brendan Gregg 推荐的火焰图频率)
perf record -F 99 -g -a -- sleep 10- 99 Hz 足以捕获有统计意义的样本,且自身开销极低(< 0.1% CPU)
- 避免与系统定时器(100/250/1000 Hz)谐振
-c(周期模式)
bash
# 每 100,000 个 CPU cycle 采样一次
perf record -c 100000 ./your_program- 适合需要固定采样精度的场景
- 对短程序,
-c可保证足够的采样点数
五、调用栈回溯方式(--call-graph)
| 模式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| fp | 利用 frame pointer(%rbp)回溯 | 最快,零额外开销 | 需要 -fno-omit-frame-pointer 编译 |
| dwarf | 利用 DWARF 调试信息展开栈 | 无需 frame pointer | 开销较大,perf.data 更大 |
| lbr | 利用 Intel LBR(Last Branch Record) | 精确,无 frame pointer 要求 | 仅 Intel CPU;栈深度有限(通常 32 层) |
推荐:
- 可重新编译 → 加
-fno-omit-frame-pointer,用fp - 无法重新编译 → 用
dwarf(但注意 perf.data 大小) - Intel CPU + 需要高精度 → 用
lbr
六、事件选择
bash
# 默认:CPU cycles 采样(看"CPU 花时间在哪个函数")
perf record -e cycles ./your_program
# 看"指令在哪个函数"(不反映耗时,因为指令执行时间不同)
perf record -e instructions ./your_program
# 看"缓存未命中发生在哪个函数"
perf record -e cache-misses ./your_program
# 看"分支预测错误发生在哪"
perf record -e branch-misses ./your_program
# 精确采样(PEBS)
perf record -e cycles:pp ./your_program
# 同时采样多个事件(注意 multiplexing)
perf record -e cycles,instructions,cache-misses ./your_program
# 采样上下文切换事件
perf record -e sched:sched_switch -a -- sleep 10七、实战工作流
工作流 1:经典火焰图流程
bash
# 1. 采样(-F 99 + -g 记录调用栈)
perf record -F 99 -g -a -- sleep 30
# 2. 生成火焰图
perf script > perf.script
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg
# 3. 或直接在 TUI 中分析
perf report工作流 2:定位缓存未命中热点
bash
# 采样缓存未命中事件
perf record -e cache-misses -g ./your_program
# 查看每个函数的 cache-miss 占比
perf report --sort=dso,sym工作流 3:多事件对比
bash
# 分别采样(避免 multiplexing 导致的精度损失)
perf record -e cycles -o cycles.data ./your_program
perf record -e instructions -o instr.data ./your_program
# 对比两个采样文件
perf diff cycles.data instr.data八、输出与注意事项
perf.data 文件
- 默认输出到当前目录的
perf.data - 包含原始采样数据、符号表、build-id 等信息
- 可以用
perf report -i <file>指定分析其他文件
常见陷阱
- 符号解析失败:编译时必须加
-g(调试符号),优化-O2保留行号需加-g -fno-omit-frame-pointer - 采样频率与程序时长:短程序(< 1 秒)可能采样不足 10 个点,改用
-c降低周期 - 权限:
-e cycles:pp等精确事件需要/proc/sys/kernel/perf_event_paranoid≤ 1 或 root - 数据丢失:高负载下 mmap 缓冲区可能溢出,
perf record结束时会报告LOST事件数量。增大-m可缓解
九、与相关文档的交叉引用
| 下一步 | 文档 |
|---|---|
| 打开采样数据 | perf-report.md |
| 生成火焰图 | perf-flamegraph.md |
| 汇编级分析 | perf-annotate.md |
| 对比优化前后 | perf-bench-diff |
| 理解采样原理 | perf-internals.md |
十、一句话总结
perf record -F 99 -g是性能分析的"CT 扫描"——以每秒 99 次的频率给 CPU 拍快照,记录每个瞬间"CPU 在执行哪个函数的哪条指令",积累足够样本后就能还原程序的执行画像。