Appearance
perf stat —— 性能统计
更新时间:2026-08-06
perf stat 统计程序或系统的整体性能指标,是性能分析的第一步——在深入分析前先用它判断"程序大概卡在哪个方向"。
关联:perf-events.md(事件体系)、PMU 原理、缓存子系统
一、perf stat 能回答什么问题
| 问题 | 用什么选项 | 看什么指标 |
|---|---|---|
| 程序 CPU 效率如何? | perf stat ./prog | IPC(instructions/cycles) |
| 缓存利用率高吗? | perf stat -e cache-references,cache-misses | cache-miss 率 |
| 分支预测准确吗? | perf stat -e branches,branch-misses | branch-miss 率 |
| syscall 频繁吗? | perf stat -e context-switches,cpu-migrations | 上下文切换次数 |
| 内核态耗时占比? | perf stat -e cycles:u,cycles:k | user/kernel 周期比 |
| 结果可靠吗(多次测)? | perf stat -r 5 | 标准差 |
| 不同阶段性能? | perf stat -I 1000 | 每秒指标变化 |
二、基本使用
2.1 统计命令执行的性能
bash
perf stat ./your_program输出示例:
bash
Performance counter stats for './your_program':
1250.42 msec task-clock # 0.998 CPUs utilized
38 context-switches # 30.390 /sec
2 cpu-migrations # 1.599 /sec
145 page-faults # 115.962 /sec
4,567,890,123 cycles # 3.654 GHz
2,345,678,901 instructions # 0.51 insn per cycle
456,789,012 branches # 365.390 M/sec
12,345,678 branch-misses # 2.70% of all branches
1.253456789 seconds time elapsed
1.248901234 seconds user
0.001234567 seconds sys2.2 统计系统整体性能(持续 N 秒)
bash
perf stat -a sleep 10-a:监控所有 CPU。
2.3 显示详细信息
bash
perf stat -v ./your_program # 显示更多指标和说明
perf stat -d ./your_program # 显示额外 L1/LLC 缓存指标
perf stat -d -d ./your_program # 显示更多详细指标三、常用选项
| 选项 | 含义 | 典型场景 |
|---|---|---|
-e <event> | 指定要统计的事件 | 精确分析某个维度 |
-a | 统计所有 CPU | 系统级分析 |
-p <pid> | 统计指定进程 | 运行中进程分析 |
-t <tid> | 统计指定线程 | 线程级分析 |
-r <N> | 重复 N 次,给出平均值和标准差 | 消除抖动,建立置信度 |
-I <ms> | 每隔 ms 毫秒输出一次 | 看指标随时间变化 |
-x <sep> | CSV 格式输出(分隔符) | 脚本/管道处理 |
--pre <cmd> | stat 之前执行的命令 | 清理缓存等前置操作 |
--post <cmd> | stat 之后执行的命令 | 后置清理 |
--per-core | 按 CPU 核分别统计 | 看负载均衡 |
--per-thread | 按线程分别统计 | 多线程程序各线程差异 |
--no-merge | 不合并同名事件 | 避免 multiplexing 误读 |
四、事件指定(-e)
4.1 修饰符
bash
# 只看用户态
perf stat -e cycles:u ./prog
# 只看内核态
perf stat -e cycles:k ./prog
# 用户态+内核态
perf stat -e cycles:u,cycles:k ./prog
# 精确级别(p = precise,利用 PEBS/AMD IBS)
perf stat -e instructions:pp ./prog修饰符速查:
| 修饰符 | 含义 |
|---|---|
u | 用户态 |
k | 内核态 |
h | Hypervisor |
p / pp / ppp | 精确级别(precise sampling) |
关键陷阱:
perf stat -e cycles:u只统计用户态周期。对 syscall-heavy 程序,内核态消耗被完全屏蔽,会严重低估真实开销。详见 perf 实战案例集 案例三/四。
4.2 常用事件组合
bash
# 快速诊断三件套
perf stat -e cycles,instructions,cache-references,cache-misses ./prog
# 分支预测
perf stat -e branches,branch-misses ./prog
# 上下文切换
perf stat -e context-switches,cpu-migrations ./prog
# 用户态 vs 内核态(终极诊断模板)
perf stat -e cycles:u,cycles:k,instructions:u,instructions:k ./prog
# CPU 前端/后端停顿
perf stat -e stalled-cycles-frontend,stalled-cycles-backend ./prog五、输出字段解读
| 字段 | 含义 | 判断标准 |
|---|---|---|
| task-clock (ms) | 进程实际占用的 CPU 时间 | 远小于 wall-clock → IO 等待 |
| context-switches | 上下文切换次数 | /sec > 1000 → 切换频繁 |
| cpu-migrations | 跨核迁移次数 | > 0 → NUMA 亲和性可能有问题 |
| page-faults | 缺页异常次数 | 大量 minor→内存分配方式有问题 |
| cycles | CPU 周期数 | — |
| instructions | 执行的指令数 | 结合 cycles 算 IPC |
| IPC | instructions / cycles | < 0.5→CPU效率低;> 1.5→良好;> 2→优秀 |
| branches | 分支指令数 | — |
| branch-misses | 分支预测错误数 | > 5% → 分支预测压力大 |
| cache-references | 缓存访问次数 | — |
| cache-misses | 缓存未命中次数 | > 10% → 缓存效率低 |
| time elapsed | 墙钟时间(秒) | 包含所有等待/阻塞 |
六、重复测量(-r)
单次测量受系统抖动影响,多次测量更可靠:
bash
perf stat -r 5 ./your_program输出会额外显示每列的平均值和标准差:
bash
4,567,890,123 cycles ( +- 0.23% )标准差 > 5% 说明系统负载波动大,需在安静环境下重测或增加 -r 次数。
七、间隔模式(-I)
bash
# 每秒输出一次(毫秒为单位)
perf stat -I 1000 -a sleep 10输出:
bash
# time counts unit events
1.001234567 12,345,678,901 cycles
1.001234567 5,678,901,234 instructions
2.002345678 11,234,567,890 cycles
2.002345678 5,123,456,789 instructions
...适合看指标的时间趋势——比如前段计算密集(cycles 高),后段 IO 阻塞(cycles 骤降)。
八、CSV 输出(-x)
bash
perf stat -x, -o perf_stat.csv ./your_program输出为机器可读格式,适合用 Python/pandas 或 awk 做批量分析。
九、常见使用场景
场景 1:判断程序是 CPU 型还是 IO 型
bash
perf stat ./your_program看 task-clock vs time elapsed:
task-clock≈time elapsed→ CPU 密集型task-clock<<time elapsed→ IO/sleep 密集型
场景 2:评估编译器优化效果
bash
perf stat -r 3 ./prog_o0
perf stat -r 3 ./prog_o2对比 instructions、cycles、IPC、branch-misses。
场景 3:判断是否受缓存性能拖累
bash
perf stat -e cycles,instructions,cache-references,cache-misses,L1-dcache-loads,L1-dcache-load-misses ./your_program- L1 miss rate < 5% → 缓存利用良好(如
O2优化后的纯计算程序) - L1 miss rate > 50% → 内存访问模式有问题(如
O0未优化、跨步过大) - LLC miss 很多 → 数据量超出缓存,或访问模式跳跃
场景 4:判断内核态 vs 用户态开销
bash
perf stat -e cycles:u,cycles:k ./your_programcycles:k占比 < 5% → 纯计算,基本不进内核cycles:k占比 > 30% → syscall 密集型(如大量 write/read)
十、注意事项
- multiplexing 问题:当指定事件数超过 PMU 硬件计数器数量时,perf 会自动分时复用。此时计数是估算值而非精确值。加
--no-merge并检查输出中的(scaled from XX%)提示。 time elapsed≠ 程序自己计时的运行时间:perf stat的time elapsed包含进程创建、退出、fork/exec、内核初始化的所有时间。程序自己用clock_gettime()算的只是业务逻辑时间。- 首次运行预热:首次运行可能因冷缓存导致 cache-misses 偏高。用
-r 3看多次结果。 - 权限:部分硬件事件需要 root 或
CAP_PERFMON。
十一、与相关文档的交叉引用
| 下一步 | 适用场景 | 文档 |
|---|---|---|
| 找到了热点 → 采样分析 | IPC 低、cache-miss 高 | perf-record.md |
| 想知道哪些函数最慢 | 需要调用栈 | perf-report.md |
| 想看 syscall 层面 | context-switches 多 | perf-trace.md |
| 事件体系参考 | 不知道用什么事件 | perf-events.md |
syscall-heavy 的 :u 陷阱 | cycles:k 占比高 | perf 案例集 |
| 缓存未命中深层分析 | L1/LLC miss 高 | perf-c2c.md |
| 上下文切换多 → 调度分析 | cswch 高 | perf-sched.md |
十二、一句话总结
perf stat是性能分析的"验血报告"——用-e cycles:u,cycles:k,instructions:u,instructions:k四字段 3 秒内判断程序类型,用 IPC 和 cache-miss 率快速缩小问题范围。