3、perf 工具详解:perf stat、perf record、perf report、perf top 实战
好,咱们今天来啃一块硬骨头——perf。这玩意儿是 Linux 性能分析的瑞士军刀,我这些年做性能优化,几乎天天跟它打交道。说实话,刚开始接触 perf 的时候我也觉得命令太多,参数太杂。但用久了你会发现,核心就四个子命令:perf stat、perf record、perf report、perf top。把这四个吃透了,80% 的性能问题你都能搞定。
perf stat:看一眼全局指标
perf stat 说白了就是「性能计数器快照」。它不采样,不记录,就是跑完程序后给你一张成绩单。
我个人习惯,拿到一个陌生程序,第一件事就是跑 perf stat。为什么?因为快啊!几秒钟就能知道 CPU 利用率、缓存命中率、分支预测准确率这些关键指标。
# 最简单的用法
perf stat ./my_program
# 如果你想看更详细的硬件事件
perf stat -e cycles,instructions,cache-misses,cache-references ./my_program
输出大概长这样:
Performance counter stats for './my_program':
1,234,567,890 cycles # 3.45 GHz
987,654,321 instructions # 0.80 insn per cycle
12,345 cache-misses # 3.2% of all cache refs
0.358234987 seconds time elapsed
instructions per cycle(IPC)。如果 IPC 低于 0.5,说明你的程序大概率在等内存或者被分支预测拖累了。我在项目中遇到过一段图像处理代码,IPC 只有 0.3,后来发现是频繁的随机内存访问导致缓存疯狂 miss。
perf record & perf report:抓现场,事后分析
perf stat 只能看个大概,真要定位问题还得靠 perf record。它就像黑匣子,把程序运行时的采样数据记录下来。
# 默认按 CPU 周期采样
perf record ./my_program
# 指定采样频率(每秒 1000 次)
perf record -F 1000 ./my_program
# 只采样某个 PID
perf record -p 12345 sleep 10
采样完成后,当前目录会生成一个 perf.data 文件。然后我们用 perf report 来分析:
perf report
你会看到一个交互式的调用链界面,按百分比排序,告诉你哪些函数最耗 CPU。嗯,这里要注意:默认显示的是 符号名,如果你的程序没加 -g 编译选项,看到的可能是一堆地址。
-g 和 -fno-omit-frame-pointer。记住,perf 依赖帧指针来展开调用栈,这两个选项缺一不可。
perf top:实时盯着看
perf top 相当于动态版的 perf report。它实时采样整个系统(或指定进程),按 CPU 消耗排序,每秒刷新一次。
# 查看整个系统的热点
perf top
# 只看某个进程
perf top -p 12345
# 只看内核态
perf top -k
这个命令我用的场景很明确:线上问题排查。比如某个服务突然 CPU 飙高,我直接 ssh 上去跑 perf top,几秒钟就能看到是哪个函数在疯狂吃 CPU。有一次数据库 CPU 100%,perf top 一看,居然是锁竞争导致的 spinlock 自旋,而不是 SQL 查询本身的问题。
perf stat → 看整体指标
perf record + report → 事后深挖调用链
perf top → 实时抓热点
实战:定位一个 CPU 密集型瓶颈
咱们来走一遍完整流程。假设有个程序 slow_math 跑得很慢:
# 第一步:全局看一眼
perf stat ./slow_math
# 发现 IPC 只有 0.4,说明有问题
# 第二步:采样
perf record -F 99 ./slow_math
# 第三步:分析
perf report
# 第四步:看到热点函数是 compute_hash()
# 然后去代码里优化这个函数
你看,四步走,清晰明了。我刚开始用 perf 的时候总想一步到位,结果经常被海量数据淹没。后来学乖了:先 stat 看方向,再 record 抓细节,最后 report 定位。
一张图理清 perf 工具链
下面这张 SVG 图是我自己画的,把 perf 四个核心命令的关系和适用场景串起来了。你想想看,是不是一目了然?
几个实用参数,记下来不吃亏
| 参数 | 作用 | 我的使用场景 |
|---|---|---|
-e |
指定要监控的事件 | 只看 cache-misses 时用 |
-F |
设置采样频率 | 线上用 99 避免太高负载 |
-g |
记录调用栈 | 必须加,否则看不到调用链 |
-p |
指定进程 PID | 排查线上服务时用 |
--call-graph dwarf |
用 DWARF 调试信息展开栈 | 没有帧指针时的备选方案 |
-F 10000,结果 perf 自己占用了 20% 的 CPU,这叫「观察者效应」。一般 99 或 1000 就够用了。
好了,perf 的四个核心命令就讲到这里。说白了,perf stat 是体检报告,perf record 是录像机,perf report 是播放器,perf top 是监控摄像头。把这四个工具用好,大部分性能问题你都能找到根因。下次遇到 CPU 飙高或者程序跑得慢,别急着拍脑袋猜,先跑一遍 perf 再说。
想要更多资料,联系可可