perf

Perf工具

安装

下载

先下载对应内核版本的perf源码:https://cdn.kernel.org/pub/linux/kernel/tools/perf/

编译安装

1
2
3
4
5
6
7
tar -xvf perf-5.10.0.tar.gz 
cd perf-5.10.0
cd tools/perf/
make
sudo cp perf /usr/local/bin

/usr/local/bin/perf --version

perf 使用

perf 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
annotate        读取perf.data(由perf record生成)并结合源代码展示详细的性能分析结果,包括CPU执行热点、函数调用栈等信息。
archive 使用perf.data文件中找到的带构建标识符的对象文件创建归档文件,便于后续对这些对象文件进行调试或者分析
bench 通用基准测试套件框架,允许用户定义和运行多种基准测试场景,用于评估系统在不同条件下的性能表现。
buildid-cache 管理perf用来关联二进制文件与其符号表信息的构建ID缓存,可以添加、删除或查看缓存内容。
buildid-list 列出perf.data文件中的构建标识符
c2c 共享数据C2C/HITM分析器:针对共享数据缓存一致性(Cache-to-Cache)和高速缓存命中(Hit in Translation)进行分析的工具,帮助诊断多核心间的缓存交互问题。
config 读取和设置perf配置文件中的变量,用于个性化perf的行为或指定默认参数。
data 提供一系列与perf.data文件相关联的操作,如检查文件内容、转换格式等。
diff 比较两个或多个perf.data文件,分析并展示它们之间的性能差异,常用于对比不同条件下系统的性能变化。
evlist 列出perf.data文件中的事件名称,这些事件可能包括硬件性能计数器事件、软件事件、tracepoint事件等。
ftrace 内核ftrace功能的简单包装器,允许实时追踪和分析内核函数调用路径。
inject 过滤器,用于向事件流中添加附加信息,增强事件的数据量和丰富度,便于更加深入地分析性能问题
iostat 显示I/O性能指标,如块设备读写速率、I/O操作延时等
kallsyms 在运行中的内核中搜索符号
kmem 用于跟踪/测量内核内存属性的工具,如分配、释放、碎片率等
kvm 用于跟踪/测量KVM虚拟机操作系统性能的工具
list 列出所有符号事件类型
lock 分析系统中锁的获取和释放行为,包括锁竞争、等待时间等,有助于发现潜在的并发瓶颈
mem 对内存访问模式进行分析,包括页错误、缓存未命中的次数、内存带宽使用等。
record 执行命令并将其性能概要记录到perf.data中
report 读取perf.data(由perf record创建)并显示概要
sched 用于跟踪/测量调度器属性(延迟)的工具,从而优化进程调度策略。
script 读取perf.data(由perf record创建)并显示跟踪输出
stat 执行命令并收集性能计数器统计信息
test 运行内置的一系列sanity测试,确保perf工具自身正确性和稳定性。
timechart 工具用于可视化工作负载期间的系统整体行为
top 系统性能分析工具,类似于Linux的top命令,但专注于性能分析,显示正在运行进程的实时性能统计数据。
version 显示perf二进制文件的版本信息
trace 类似strace的工具,用于跟踪系统调用和信号

perf 基本语法

perf 命令的基本语法格式为:

1
perf [--version] [--help] COMMAND [ARGS]

常用子命令包括:

  • stat:性能计数器统计
  • record:记录性能数据
  • report:分析记录的数据
  • top:实时性能监控
  • list:列出可用事件
  • annotate:源代码级分析
perf stat

统计命令执行过程中的各种硬件和软件事件。

1
perf stat [options] command [command-options]

常用选项:

  • -e:指定要监控的事件
  • -p:监控指定进程ID
  • -a:监控所有CPU
  • -r:重复运行并显示平均值
  • -d:显示更多详细事件

示例:

1
2
3
4
5
6
7
8
# 统计 ls 命令的执行情况*
perf stat ls

# 监控指定进程*
perf stat -p 1234

# 监控特定事件*
perf stat -e cycles,instructions,cache-misses ls
perf record

记录性能数据到文件(默认 perf.data)。

1
perf record [options] command [command-options]

常用选项:

  • -g:记录调用图(call graph)
  • -a:分析所有CPU的数据
  • -C:只采集指定 CPU 数据
  • -F:采样频率(Hz),即一秒钟采样多少次
  • -p:指定要采样的进程ID
  • -o:指定输出文件
  • -e:指定要记录的事件

示例:

1
2
3
4
5
6
7
8
9
10
# 记录 ls 命令的执行情况
perf record ls

# 以1000Hz频率记录进程
perf record -F 1000 -p [进程pid] -g -- sleep 10
# -F指定采样的频率为1000Hz,即一秒钟采样1000次
# -p指定要采样的进程ID
# -g表示记录调用栈信息
# sleep 10 表示持续10秒
# perf会将采集到的性能数据写入当前目录下的perf.data文件中
perf report

分析 perf record 记录的数据。

1
perf report [options]

常用选项:

  • -i:指定输入文件
  • -n:显示样本数量
  • --stdio:文本模式输出
  • -g:显示调用图
  • -s:按指定字段排序

示例:

1
2
3
4
5
# 分析默认的 perf.data 文件
perf report

# 分析指定文件并以文本模式输出
perf report -i perf.data.old --stdio
perf top

实时显示系统中最消耗资源的函数。

1
perf top [options]

常用选项:

  • -e:指定监控事件
  • -p:监控指定进程
  • -K:隐藏内核符号
  • -U:隐藏用户空间符号
  • -g:显示调用图

示例:

1
2
3
4
5
# 实时监控系统性能
perf top

# 监控特定事件
perf top -e cache-misses
perf list

列出所有可监控的事件。

1
perf list [hw|sw|cache|tracepoint|pmu|event_glob]

示例:

1
2
3
4
5
# 列出所有事件
perf list

# 列出硬件缓存事件
perf list cache

perf 事件类型

perf 可以监控多种类型的事件:

事件类型 描述 示例
Hardware CPU硬件事件 cycles, instructions
Software 内核软件事件 context-switches, page-faults
Cache 缓存相关事件 cache-references, cache-misses
Tracepoints 内核静态跟踪点 syscalls, block, sched
PMU 处理器特定事件 (vendor specific)
Breakpoints 断点事件 mem:[:access]

perf 实际应用示例

分析程序性能瓶颈

1
2
3
4
5
# 记录程序执行
perf record -g .**/**my_program

# 分析结果
perf report -g

查找CPU热点函数

1
perf top -p $(pidof my_program)

比较两次运行的性能差异

1
2
3
4
5
6
7
8
# 第一次运行
perf record -o perf.data.1 ./my_program input1

# 第二次运行
perf record -o perf.data.2 ./my_program input2

# 比较差异
perf diff perf.data.1 perf.data.2

分析系统调用

1
2
3
4
5
# 列出可用的系统调用跟踪点
perf list 'syscalls:*'

# 跟踪open系统调用
perf stat -e 'syscalls:sys_enter_open' -a sleep 10

生成火焰图

获取火焰图生成脚本

1
git clone https://github.com/brendangregg/FlameGraph.git

生成火焰图

1
2
3
4
5
6
7
8
9
10
# stackcollapse-perf.pl 脚本只支持文本格式的调用栈数据,无法直接处理 perf 的二进制数据
# 把 perf.data 里的内容转换成可读的文本格式
sudo perf script -i perf.data > perf.unfold

# stackcollapse-perf.pl 是 FlameGraph 工具集里的 Perl 脚本,它会把每条调用链“折叠”成一行,并统计重复路径出现的次数
./stackcollapse-perf.pl perf.unfold > perf.folded

# 最后生成 svg 图
# flamegraph.pl 是 FlameGraph 的主脚本,专门将折叠数据转成火焰图(SVG矢量图)
./flamegraph.pl perf.folded > perf.svg

火焰图含义

火焰图是基于perf结果产生的svg图片,用来展示cpu的调用栈

y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

火焰图就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。

互动性

鼠标悬浮

火焰的每一层都会标注函数名,鼠标悬浮时会显示完整的函数名、抽样抽中的次数、占据总抽样次数的百分比

1
Function:reader_loop (2,311 samples, 78.00%)

点击放大

点击任何一层,火焰图会水平放大,该层会占据所有宽度,显示详细信息

左上角会同时显示”Reset Zoom”,点击该链接,图片就会恢复原样。

搜索

按下 Ctrl + F 会显示搜索框,用户可以输入关键词或正则表达式,所有符合条件的函数名会高亮显示

局限

两种情况下,无法画出火焰图,需要修正系统行为。

  • 调用栈不完整:当调用栈过深时,某些系统只返回前面的一部分(比如前10层)

  • 函数名缺失:有些函数没有名字,编译器只用内存地址来表示(比如匿名函数)

参考链接:


perf
https://tomwithkernel.github.io/debug/perf/
作者
Tom
发布于
2024年5月10日
更新于
2025年9月16日
许可协议