Perf 工具与火焰图使用指南
参考资料
目录
- [一、Perf 工具介绍](#一、Perf 工具介绍 "#%E4%B8%80perf-%E5%B7%A5%E5%85%B7%E4%BB%8B%E7%BB%8D")
- [二、Perf 工作模式](#二、Perf 工作模式 "#%E4%BA%8Cperf-%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F")
- [三、Perf 安装](#三、Perf 安装 "#%E4%B8%89perf-%E5%AE%89%E8%A3%85")
- [四、Perf 使用方法](#四、Perf 使用方法 "#%E5%9B%9Bperf-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95")
- 五、生成火焰图
一、Perf 工具介绍
perf 命令(performance 的缩写),是 Linux 系统提供的性能分析工具集,包含多种子工具,能够监测多种硬件及软件性能指标,包括 CPU、内存、IO 等,这些可监测指标我们称为 Event。
二、Perf 工作模式
2.1 计数模式
记录 perf 执行过程中 event 的出现次数。
2.2 采样模式
在 perf 执行过程中,按照指定频率去采样 event,每次采样时,记录当前性能指标信息(CPU、进程 ID、运行栈等)。
⚠️ 注意:这种方式由于每次都记录信息,所以额外的资源消耗是比较大的,需要权衡采样频率。
三、Perf 安装
3.1 通过包管理器安装(Ubuntu)
对于 Ubuntu 等 Linux 系统发行版,都提供了对应的包,只要根据内核版本进行安装即可:
bash
# 在 Ubuntu 下安装
sudo apt-get install linux-tools-common
sudo apt-get install linux-tools-"$(uname -r)"
sudo apt-get install linux-cloud-tools-"$(uname -r)"
sudo apt-get install linux-tools-generic
sudo apt-get install linux-cloud-tools-generic
💡 提示:Linux 系统可能无法找到和 kernel 版本相同的工具安装包,可以使用其他版本替换。
如果版本不匹配,可以手动创建软链接:
bash
sudo rm /usr/bin/perf
sudo ln -s /usr/lib/linux-tools-4.15.0-163/perf /usr/local/bin/perf
3.2 从源码编译安装(推荐)
⚠️ 重要提示 :不能直接
make,需要先安装某些依赖,否则会导致某些异常。缺少某些库请参照编译的提示进行安装。
内核资源:
- 内核官网:www.kernel.org/
- 内核下载地址:ftp.sjtu.edu.cn/sites/ftp.k...
编译步骤:
bash
# 1. 下载源码
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# 2. 切换至对应的版本分支
cd linux
git branch -r # 查看所有远程分支
git branch -a # 查看所有分支
git checkout v5.4 # 切换到 v5.4 分支
# 3. 编译安装 perf
cd tools/perf
make
# 4. 测试 perf 是否成功安装
cd ../..
sudo perf top
四、Perf 使用方法
4.1 perf list
查看当前系统支持的性能事件。使用 perf list 命令可以显示当前软硬件环境下支持的所有事件:
| 事件类型 | 说明 | 示例 |
|---|---|---|
| Hardware Event | 由 PMU 部件产生,在特定条件下探测性能事件 | CPU 周期、分支指令、TLB 重填例外、Cache 缺失 |
| Software Event | 内核产生的事件,统计操作系统相关性能事件 | 系统调用次数、上下文切换次数、任务迁移次数、缺页例外次数 |
| Tracepoint Event | 内核中静态 tracepoint 触发的事件 | slab 分配器的分配次数等 |
4.2 perf top
类似 top 命令,主要用于实时分析各个函数在某个性能事件上的热度,能够快速定位热点函数,包括应用程序函数、模块函数与内核函数,甚至能够定位到热点指令。
🔐 执行需要 root 权限
常用参数:
| 参数 | 说明 |
|---|---|
-e <event> |
指明要分析的性能事件 |
-p <pid> |
仅分析目标进程及其创建的线程 |
4.3 perf stat
用于统计 event 出现的次数(计数模式)。
默认事件说明:
| 事件名称 | 说明 |
|---|---|
cpu-clock |
任务真正占用的处理器时间(ms)。CPUs utilized = cpu-clock / time elapsed,值高说明程序多数时间花费在 CPU 计算上而非 IO |
context-switches |
上下文的切换次数 |
CPU-migrations |
处理器迁移次数。Linux 为维持多处理器负载均衡,会将任务从一个 CPU 迁移到另一个 CPU |
page-faults |
缺页异常次数。页面未建立、不在内存、映射关系未建立、TLB 不命中、权限不匹配等都会触发 |
cycles |
消耗的处理器周期数 |
instructions |
执行的指令数。IPC 为平均每个 CPU cycle 执行的指令数 |
branches |
遇到的分支指令数 |
branch-misses |
预测错误的分支指令数 |
参数说明:
bash
-e <event> # 指定性能事件(可以是多个,用 , 分隔)
-p <pid> # 指定待分析进程的 pid(可以是多个,用 , 分隔)
-t <tid> # 指定待分析线程的 tid(可以是多个,用 , 分隔)
-a # 从所有 CPU 收集系统数据
-d # 打印更详细的信息,可重复 3 次
# -d:L1 和 LLC data cache
# -d -d:dTLB 和 iTLB events
# -d -d -d:增加 prefetch events
4.4 perf record
采样模式,perf 收集采样信息并记录在文件中,可以离线分析。使用 perf report 解析收集的采样数据文件。
参数说明:
| 参数 | 说明 |
|---|---|
-e |
选择性能事件 |
-p |
待分析进程的 id |
-t |
待分析线程的 id |
-a |
分析整个系统的性能 |
-C |
只采集指定 CPU 数据 |
-F |
采样频率,每秒多少次 |
-c |
事件的采样周期 |
-o |
指定输出文件,默认为 perf.data |
-A |
以 append 的方式写输出文件 |
-f |
以 OverWrite 的方式写输出文件 |
-g |
记录函数间的调用关系 |
使用示例:
bash
sudo perf record -e cpu-clock -g -p 2548
# -g 告诉 perf record 额外记录函数的调用关系
# -e cpu-clock 监控的指标为 cpu 周期
# -p 指定需要 record 的进程 pid
💡 采样一段时间后,可以使用
Ctrl+C停止命令,这时会生成perf.data文件(默认文件名)
4.5 perf report
主要用来分析 perf record 生成的 perf.data 文件。
五、生成火焰图
5.1 操作流程
采集数据] --> B[perf script
导出文本] B --> C[stackcollapse-perf.pl
折叠堆栈] C --> D[flamegraph.pl
生成 SVG] D --> E[浏览器查看
火焰图]
5.2 第一步:采样并记录性能数据
bash
# 对 CPU 所有进程 99Hz 采集,执行 60 秒后采集完成,当前目录生成 perf.data 文件
perf record -F 99 -a -g -- sleep 60
perf script > out.perf
# 或者:对进程 id 181 采集,采集时间 60 秒,执行期间不要退出
perf record -F 99 -p 181 -g -- sleep 60
perf script > out.perf
5.3 第二步:用 FlameGraph 工具解析
工具仓库 :github.com/brendangreg...
bash
# 克隆工具仓库
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
# 折叠堆栈信息
./stackcollapse-perf.pl out.perf > out.folded
# 生成火焰图
./flamegraph.pl out.folded > kernel.svg
5.4 解读火焰图
火焰图是基于 stack 信息生成的 SVG 图片,用来展示 CPU 的调用栈。
顶部是正在执行的函数
下方是父函数] X[X 轴:抽样数/执行时间
宽度越大执行时间越长
按字母顺序排列] end
关键要点:
| 元素 | 说明 |
|---|---|
| 方框 | 每个方框代表一个函数 |
| 宽度 | 方框越宽,代表执行时间越久 |
| 高度 | 楼层越高,代表调用栈越深 |
| 顶层 | 最顶层的函数是叶子函数(正在执行的函数) |
| 平顶 | 如果有"平顶"(plateaus),表示该函数可能存在性能问题 |
🎯 分析技巧:火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶",就表示该函数可能存在性能问题,是优化的重点目标。
附录:快速参考卡片
bash
# 实时查看热点函数
sudo perf top -p <pid>
# 统计性能事件
sudo perf stat -p <pid> -d
# 采样并生成火焰图(完整流程)
sudo perf record -F 99 -p <pid> -g -- sleep 60
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl out.folded > flame.svg