登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux perf stat 如何只统计某个进程的硬件事件

来源:17golang原创

时间:2026-09-10 11:25:55 185浏览 收藏

如果只想观察一个已经运行的 Linux 进程,核心写法是把目标 PID 交给 perf stat -p,再用 -e 指定硬件事件:

# -p 只附着到已有进程;-e 选择硬件事件,两个事件用逗号分隔
sudo perf stat -p 12345 -e cycles,instructions

12345 换成目标进程的真实 PID。不要同时加 -a,因为 -a 表示扩大到所有 CPU 上的系统范围统计。perf stat 统计的是事件计数,不是采样火焰图;如果只想看一段时间,可以在目标进程持续运行时按 Ctrl+C 结束统计,或使用 --timeout 设定时间窗口。

要点速览
  • -p PID 选择已有进程,-e cycles,instructions 选择要读取的硬件事件。
  • -a 是全系统范围选项;和“只统计某个进程”的目标相反,不能为了排错随手加上。
  • 事件名称要先用本机 perf list 确认;权限、PMU 支持、进程线程和统计时间都会影响结果提示。

-p PID 为什么能把统计对象限定到一个进程

perf stat 有三种容易混淆的用法:直接跟命令表示统计该命令的运行过程,-p PID 表示附着到已经存在的进程,-a 则把范围扩展到所有 CPU 的系统活动。本文的问题属于第二种,最小命令应是:

# 先确认 PID,再附着到它;不要把 -a 混入单进程统计
pidof my-service
sudo perf stat -p 12345 -e cycles,instructions

底层接口会把性能事件与任务关联起来,所以 -p 的关键不是“过滤输出”,而是改变计数器的目标对象。进程创建的线程也要纳入考虑:普通进程级附着通常围绕该任务的线程集合统计;如果你只想观察一个明确的线程,应先拿到线程 ID,再看本机 perf 版本对线程选项的支持。

Linux perf stat 通过 -p PID 关联目标进程、线程集合和 CPU PMU 硬件计数器并与 -a 全系统范围区分的静态关系图
图1:-p PID 把统计对象约束在目标进程及其线程集合,-a 则是另一种全系统范围。

-e 事件名称应该怎样选择

-e 只负责选择要计数的事件,不会替你保证每台机器都支持同一个名字。cycles 通常用来观察 CPU 周期,instructions 用来观察退休指令,但具体别名和可用性仍取决于处理器 PMU、内核和 perf 版本。先运行:

# 查看当前机器能识别的事件;只从输出中选择实际存在的名称
perf list | less

# 选定事件后再附着目标进程
sudo perf stat -p 12345 -e cycles,instructions

如果输出出现 ,优先检查事件名和 PMU 支持;如果出现 或 scaled 提示,则要结合权限、计数器资源和统计时间判断,不能把它当成目标进程的真实零值。一次选择太多事件还可能让硬件计数器需要复用,结果中的运行时间比例就更值得关注。

Linux perf stat 的 -e 事件选择经过 perf list、PMU 支持、权限策略和时间窗口后形成结果计数的静态关系图
图2:事件名称、PMU 支持、权限策略和统计时间共同决定结果计数如何解释。

多线程、时间窗口和权限边界怎么处理

单进程统计最常见的误差来源不是命令拼写,而是目标在统计期间发生了变化。目标进程如果很快退出,附着可能来不及建立;如果服务会派生工作线程或子进程,应先明确你要的是主进程本身、线程集合,还是包含子进程的更大范围。不要用一个模糊的全系统统计替代这个选择。

# 用 10 秒窗口观察已有进程;--timeout 的单位按 perf stat 手册使用毫秒
sudo perf stat --timeout 10000 -p 12345 -e cycles,instructions

# 事件过多时先缩小集合,避免只得到低覆盖率的计数
sudo perf stat -p 12345 -e cycles

如果收到权限错误,可以检查 /proc/sys/kernel/perf_event_paranoid、当前用户能力和发行版安全策略,但不要为了得到一个数字就长期降低系统保护。容器、虚拟机和云主机还可能没有向来宾暴露 PMU;这时换事件名未必有用,应先确认运行环境是否允许性能计数。

现象或参数它说明什么优先检查
-p 12345附着已有进程PID 是否仍存在、进程是否在统计窗口内运行
-e cycles,instructions选择两个硬件事件perf list 是否列出对应事件
-a扩大到全系统范围是否误把它加入单进程排查命令
当前环境不支持该事件CPU PMU、内核和 perf 版本
没有得到可用计数权限、计数器资源和运行时间

怎样复查结果没有统计错对象

拿到输出后按四项复查:命令里是否确实出现目标 PID;事件名是否来自本机 perf list;统计期间 PID 是否被复用或进程是否提前退出;输出是否带有未支持、未计数或复用比例提示。若目标是一个长期服务,建议先记录进程启动时间和命令行,再开始附着,避免 PID 生命周期变化造成误判。

最终可以把命令收敛成一条便于审阅的形式:

# 固定目标、固定事件和固定窗口,便于把结果交给同事复查
sudo perf stat --timeout 10000 -p 12345 -e cycles,instructions 2> perf-stat-12345.txt

这里的重定向只是保存 perf 的统计输出,不会把全系统数据自动变成进程数据;真正的范围仍由 -p 决定。更换 PID、事件或运行环境后,应该重新检查支持情况,不要直接横向比较两个不具备相同 PMU 条件的数字。

相关问题

只写 perf stat -p PID 可以吗?

可以,perf 会使用默认事件集合,但文章排查硬件事件时更建议显式写出 -e,这样同事能知道你比较的到底是哪些计数器。

-p PID 和直接写 perf stat command 有什么区别?

前者附着已经存在的进程,后者由 perf 启动并统计命令。要观察正在运行的服务,用 -p;要控制完整生命周期和启动参数,直接统计命令更容易复现。

为什么 cycles 事件显示 not supported?

可能是当前架构、虚拟化环境、内核或 perf 版本没有暴露这个事件。先用 perf list 查本机名称,再确认 PMU 是否可用,不要把不支持当成零周期。

统计一个进程会不会包含它的线程?

应把它理解为任务范围问题:进程可能有多个线程,具体纳入范围受 perf 版本和选项影响。需要单线程结论时,明确取得线程 ID 并使用本机手册支持的线程选项,然后单独复查。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>