Linux 性能分析工具 perf

perf 是 Linux 中标准的 Profiler,常用于 CPU Profiling、CPU flame Graphs、Syscall Tracing 等。

perf 命令行操作

perf 常用子命令,命令帮助及选项参数帮助文档可查看 man perfman perf-recordman perf-report

子命令 说明 示例
record 进行 Profile 操作并将结果写入 perf.data
report 读取 perf.data (created by perf record)并展示 Profile 内容
script 读取 perf.data (created by perf record)并展示堆栈内容
stat 显示 PMC(Performance Monitor Counter) 统计数据
list 列出系统支持的事件(Event)列表

perf record 命令常用选项

选项 说明 示例
-F, --freq= 指定 Profile 的频率,使用 max 以当前系统允许的最大频率(对应内核参数 kernel.perf_event_max_sample_rate)进行 Profile
通常建议 99 Hz
-a, --all-cpus 采集所有 CPU 的全局数据,默认操作
-g Kernel Space 和 User Space Stack Traces
-p, --pid= 对指定 PIDs (comma separated list) 进行采样
-e, --event= 针对 Event 进行采样追踪 perf record -F 99 -a -e sched:sched_process_exec

perf report 命令常用选项

选项 说明 示例
-n, --show-nr-samples 显示每个 Symbol 采样的数量
-s, --sort= 按照指定的(CSV)字段排序

perf 使用示例

记录使用 exec 启动的进程

通过监控系统调用事件,可以采样/追踪系统上符合条件的行为,比如以下命令追踪使用 exec 系统调用启动的进程

# perf record -F 99 -a -e sched:sched_process_exec

# perf report
Overhead Command Shared Object Symbol
40.48% runc [kernel.kallsyms] [k] exec_binprm
34.86% exe [kernel.kallsyms] [k] exec_binprm
24.57% rsync [kernel.kallsyms] [k] exec_binprm
0.06% rsync2Server.sh [kernel.kallsyms] [k] exec_binprm
0.03% watchtower [kernel.kallsyms] [k] exec_binprm

添加 -g 选项追踪详细的堆栈信息

# perf record -F 99 -a -e sched:sched_process_exec -g

# perf report
Children Self Command Shared Object Symbol
+ 59.92% 59.92% rsync [kernel.kallsyms] [k] exec_binprm
+ 59.92% 0.00% rsync ld-linux-x86-64.so.2 [.] _start
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] do_syscall_64
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] x64_sys_call
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] __x64_sys_execve
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] do_execveat_common.isra.0
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] bprm_execve
+ 59.92% 0.00% rsync [kernel.kallsyms] [k] bprm_execve.part.0
+ 40.02% 40.02% rsync2Server.sh [kernel.kallsyms] [k] exec_binprm
+ 40.02% 0.00% rsync2Server.sh ld-linux-x86-64.so.2 [.] _start
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] do_syscall_64
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] x64_sys_call
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] __x64_sys_execve
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] do_execveat_common.isra.0
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] bprm_execve
+ 40.02% 0.00% rsync2Server.sh [kernel.kallsyms] [k] bprm_execve.part.0
0.07% 0.07% sleep [kernel.kallsyms] [k] exec_binprm
0.07% 0.00% sleep ld-linux-x86-64.so.2 [.] _start
0.07% 0.00% sleep [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe
0.07% 0.00% sleep [kernel.kallsyms] [k] do_syscall_64
0.07% 0.00% sleep [kernel.kallsyms] [k] x64_sys_call
0.07% 0.00% sleep [kernel.kallsyms] [k] __x64_sys_execve
0.07% 0.00% sleep [kernel.kallsyms] [k] do_execveat_common.isra.0
0.07% 0.00% sleep [kernel.kallsyms] [k] bprm_execve
0.07% 0.00% sleep [kernel.kallsyms] [k] bprm_execve.part.0

perf 读取 PMC 统计数据

使用以下命令可以读取系统中的 PMC 统计数据,其中包含了 CPU 使用时钟、CPU Context Switch、CPU Migrations、Page-Faults 等统计信息

# perf stat -a -- sleep 10

Performance counter stats for 'system wide':

40,019.66 msec cpu-clock # 4.000 CPUs utilized
51,242 context-switches # 1.280 K/sec
4,912 cpu-migrations # 122.740 /sec
7,944 page-faults # 198.502 /sec
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses

10.004545496 seconds time elapsed

<not supported> 可能包括以下原因:

  • 缺乏硬件支持
    • 某些处理器可能不支持所需的硬件性能计数器(如 cyclesinstructions
    • 这可能出现在虚拟机环境中,尤其是未启用硬件性能监控功能的虚拟机。
  • 权限不足
    • 性能计数器访问可能需要更高权限,通常是 root 权限
  • 内核配置问题
    • perf 依赖于 Linux 内核的性能监控功能。如果内核未启用某些性能计数器,可能会导致 <not supported>
  • 禁用了特定的事件源
    • 某些环境中,特定性能监控功能可能被内核禁用(例如为了安全性)。

参考链接|Bibliography

Systems Performance: Enterprise and the Cloud v2

脚注