Linux perf stat 怎样先看 CPU 指标
来源:17golang原创
时间:2026-10-14 14:43:37 110浏览 收藏
排查 Linux 程序变慢时,第一轮不要一上来就用复杂采样。perf stat 更适合先回答一个窄问题:这段命令消耗了多少 CPU 周期,完成了多少条指令,分支和缓存是否出现异常。通常先看 cycles、instructions、branches、branch-misses,再按现象补充缓存事件。下面的命令和图示是静态说明,不代表在当前机器上实际执行过的输出。
- IPC 可用
instructions / cycles粗看流水线利用率,但不能单独证明存在某一种瓶颈。 cache-misses必须结合缓存引用、工作集和运行时间比较;不同 CPU 的事件定义可能不同。- 事件不支持、计数器复用、短任务和频率变化都会影响结论,先确认可测量再做优化。
先用默认计数建立 CPU 基线
对一个可重复的命令,先保留输入、环境和参数,只包一层 perf stat。示例中的 ./worker --input sample.dat 只是待测程序占位符。
# 先看默认软件事件和硬件事件,建立同一场景的基线
perf stat -- ./worker --input sample.dat
# 只保留最常用的 CPU 指标,便于多次结果对照
perf stat -e task-clock,cycles,instructions,branches,branch-misses -- ./worker --input sample.dat
重点不是某个绝对数字,而是同一输入下的相对变化。cycles 上升而指令数近似不变,可能意味着等待、频率或微架构效率变化;指令数和 cycles 同时上升,则可能是工作量本身变大。由 instructions / cycles 得到的 IPC 只适合做方向判断,不能跨不同 CPU 直接比较。

按问题选择缓存和分支指标
当程序的指令数没有明显增加,却出现执行时间变长,可以把缓存和分支指标放进同一次测量:
# 用事件名显式选择指标;具体可用名称以本机 perf list 为准
perf stat -e cycles,instructions,cache-references,cache-misses,branch-misses -- ./worker --input sample.dat
# 先预热,再重复测量,减少首次加载和调度噪声
perf stat -r 5 -e cycles,instructions,cache-misses -- ./worker --input sample.dat
cache-misses / cache-references 可以作为同一平台上的粗略未命中比例,但它不是“慢的证明”:顺序扫描大数据也可能有较高计数,命中率下降还可能来自工作集变大。分支未命中率升高时,再去看输入分布、分支规律和热路径,别直接把所有问题归为 CPU 缓存。
| 观察结果 | 优先动作 | 不要直接下的结论 |
|---|---|---|
| cycles 增长,instructions 接近 | 复测频率、调度和等待因素 | 不等于代码多执行了 |
| IPC 下降,cache-misses 同时上升 | 比较工作集、访问局部性和数据布局 | 不等于只需加缓存 |
| branch-misses 比例明显上升 | 检查输入分布和热路径分支 | 不等于分支预测器损坏 |
| 事件显示不可用或比例很低 | 查看 perf list、权限和计数器调度 | 不等于指标为零 |
用事件可用性校准 perf stat 结果
perf list 展示当前内核和 PMU 可识别的事件。不同架构的缓存事件名字、含义和精度并不完全一致,所以不要把某台 Intel 机器上的事件名原样搬到 ARM 或混合架构。
# 查看本机可用事件和 metric 名称
perf list
# 用较少事件避免硬件计数器不够时发生过多复用
perf stat -e '{cycles,instructions}' -- ./worker --input sample.dat
如果输出出现 ,说明事件在当前环境不能测; 则常见于事件没有获得有效计数时间。一次塞入太多事件时,perf 可能进行 multiplexing,结果会带缩放或运行比例。做指标对比时,宁可拆成两组稳定测量,也不要把不同时刻采到的事件强行算成精确比值。

重复测量后再决定下一步
一轮结果只够定位方向。先固定输入和 CPU 亲和性,确保待测进程有足够长的执行区间;短到几十毫秒的命令容易被启动、页面缺页和调度放大。对于持续运行服务,可以使用目标 PID 或较长的窗口,但要把采集窗口内的请求量记录下来,否则指标没有可比的分母。
如果 IPC 下降但缓存和分支都稳定,下一步应检查锁等待、系统调用或 I/O;如果缓存未命中和执行时间随数据规模同步增长,再看访问模式和数据布局。perf stat 的价值是把“感觉变慢”变成可复测的对照,不是替代火焰图、源码分析或业务指标。
常见问题
perf stat 默认测的是哪个对象
命令后跟可执行程序时测该命令及其子进程;不指定目标时才可能进入系统范围模式。脚本中应显式写出待测命令和参数。
cache-misses 越高就一定越慢吗
不一定。还要看缓存引用总量、内存访问延迟、工作集和程序实际耗时;高计数可能只是处理了更多数据。
为什么同一命令每次 IPC 不一样
常见原因包括输入变化、预热状态、CPU 频率、调度迁移、共享缓存竞争和计数器复用。用 -r 重复测量并记录场景后再比较。
先用少量稳定事件建立基线,再按异常选择缓存或分支指标,最后结合可用性和重复测量解释结果,这样更容易把 perf stat 的数字连接到真实优化动作。
-
290 收藏
-
192 收藏
-
131 收藏
-
206 收藏
-
407 收藏
-
132 收藏
-
458 收藏
-
326 收藏
-
489 收藏
-
113 收藏
-
436 收藏
-
119 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习