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 四个核心命令的关系和适用场景串起来了。你想想看,是不是一目了然?

perf 工具链核心命令关系图 perf stat 全局指标快照 perf record 采样记录数据 perf report 分析采样结果 perf top 实时热点监控 发现异常 生成数据 也可独立使用 💡 使用顺序:先 stat 看全局 → 发现异常用 record 采样 → report 分析热点 💡 perf top 适合线上实时排查,不需要先跑程序

几个实用参数,记下来不吃亏

参数 作用 我的使用场景
-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 再说。

一句话记住:先 stat 看方向,再 record 抓细节,report 定位,top 救火。

想要更多资料,联系可可