C++分析程序各模块耗时-perf火焰图
- 1. 简介
- 2. 安装
- 3. 测试示例
- 4. 从火焰图可以获得的信息
- 5. 生成火焰图常见问题
Reference:
- Perf Wiki
- 【性能】perf + 火焰图分析软件性能瓶颈
- 【火焰图🔥】Linux C/C++性能优化分析工具Perf使用教程
perf: Linux profiling with performance counters(带有性能计数器的Linux分析)
1. 简介
perf 是一个非常实用且深入的性能分析工具,适用于从底层硬件交互到上层应用程序逻辑的全方位性能剖析。
perf 工具的设计目的是为了帮助开发者和系统管理员分析应用程序以及内核本身的性能,寻找潜在的性能瓶颈,并据此进行针对性的优化。
2. 安装
sudo apt install linux-tools-common
// 下面步骤根据 Linux 内核来。比如查看 uname -a 得到内核版本,根据相应版本修改下面指令
sudo apt install linux-tools-5.15.0-101-generic
- 查看 perf 版本
perf --version
3. 测试示例
#include <stdio.h>
#include <stdlib.h>void long_test() {int i, j;for (i = 0; i < 1000000; i++) j = i;
}void foo2() {int i;for (i = 0; i < 10; i++) long_test();
}void foo1() {int i;for (i = 0; i < 100; i++) long_test();
}
int main(void) {foo1();foo2();
}
-
编译成二进制文件
g++ -o test test.cpp
-
使用 perf 对系统 CPU 事件做采样
采样60s,会生成一个perf.data文件(采样时间可自行设定):#方式一:对一个正在运行的进程,进行采样
perf record -p PID[这里换成要检测的进程ID] -g – sleep 60
#方式二:全新运行一个二进制文件main,进行采样
sudo perf record -F 99 -g ./test – sleep 60 -
安装火焰图
利用这个开源工具可以将报告生成可视化的svg图片,更容易查看对应的CPU开销时间和调用栈深度:git clone --depth 1 https://github.com/brendangregg/FlameGraph.git
#安装perl
yum install -y perl -
生成火焰图
生成火焰图的脚本,对二进制文件main进行10秒的采样,然后生成火焰图。
非root用户需要加sudo。perf record -g ./test sleep 10
perf script -i perf.data &> perf.unfold
#火焰图的两个功能
./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg
我自己的:
sudo perf record -g ./build_pc/dead_reckoning sleep 10
perf script -i perf.data &> perf.unfold
/home/yj/sda/third_party/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
/home/yj/sda/third_party/FlameGraph/flamegraph.pl perf.folded > perf.svg
上面的方式中,[unknown] 出现过多,可考虑将 -g(默认为 fp)
修改为 --call-graph
。可参考 使用 perf 进行性能分析时如何获取准确的调用栈
- | 优点 | 缺点 |
---|---|---|
fp | None | 默认 fp 被优化掉了根本不可用。 |
lbr | 高效准确 | 需要较新的 Intel CPU 才有此功能;2. 能记录的调用栈深度有限。 |
dwarf | 准确 | 1. 开销相对较大;2. 需要编译时附加了调试信息。 |
sudo perf record --call-graph dwarf ./build_pc/dead_reckoning sleep 10
sudo perf script -i perf.data &> perf.unfold
/home/yj/sda/third_party/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
/home/yj/sda/third_party/FlameGraph/flamegraph.pl perf.folded > perf.svg
4. 从火焰图可以获得的信息
- 调用栈从下往上,下层为父类,上层为子类。
- 点击父类缩小,点击子类放大。
- 只关注自己实现的函数名,忽略标准库中的函数。
- 总结一下,火焰图的宽度用于比较不同函数或代码路径的性能,而高度用于显示函数调用堆栈的深度。
5. 生成火焰图常见问题
- Stack count is low (1). Did something go wrong?
-> sudo perf script 时没加 root 权限。