linux性能统计工具使用总结¶
最近在优化gem5的运行速度,用到了linux的perf工具,并且生成了火焰图。 特此记录一个过程中遇到的问题,方便后续再遇到类似问题的解决。
步骤¶
perf安装¶
上面链接包含了perf所有的介绍,包括perf的安装方法,这里使用源码安装的方式进行安装,在building章节中有源码安装的方式, 思路是通过apt来下载对应系统的内核源码,在内核源码的tools/perf目录下保存了perf的源码,make并且make install即可,需要 注意的是一般源码会安装在/usr/src/目录下,所以需要sudo权限
perf生成record¶
使用 perf record命令来记录下程序的运行log,这里参考了外国友人的笔记
核心命令为
perf record --call-graph dwarf,16384 -e cpu-clock -F 997 target/release/name-of-binary <command-line-arguments>
当然我在使用的时候发现perf record -g target/release/name-of-binary 是可用的,其他参数还需要逐个确认
权限问题¶
因为我编译的时候使用了sudo权限,也没有把perf权限开放给普通用户,所以这里执行的时候也要sudo。直接通过apt-get安装的perf不需要加sudo
路径问题¶
target/release/name-of-binary 需要写绝对路径或者加./来解决
perf_event_paranoid问题¶
如果提示需要修改perf_event_paranoid,可以通过提示的方式进行永久性修改,也可以通过如下方式查看和修改
sysctl -n kernel.perf_event_paranoid
sudo sysctl -w kernel.perf_event_paranoid=-1
解析成火焰图¶
首先要安装 flamegraph
git clone https://github.com/brendangregg/FlameGraph
需要把FlameGraph中的所有pl文件加入到环境PATH中,可以把这个加入到用户目录的profile中
cd FlameGraph
echo "PATH=/path/to/FlameGraph:$PATH" >> .profile
source .profile
老版本还需要加入一个转换工具
git clone https://github.com/Yamakaky/rust-unmangle.git
cd rust-unmangle
chmod u+x rust-unmangle
echo "PATH=/path/to/rust-unmangle:$PATH" >> .profile
source .profile
生成火焰图
perf script | stackcollapse-perf.pl | stackcollapse-recursive.pl | c++filt | rust-unmangle | flamegraph.pl > flame.svg
如果遇到ERROR: No stack counts found的错误 修改当前目录下生成的perf.data的权限
sudo chown -R root:root perf.data
sudo perf script | stackcollapse-perf.pl | stackcollapse-recursive.pl | c++filt | rust-unmangle | flamegraph.pl > flame.svg
这样就可以根据火焰图来分析程序哪里比较耗时了
遇到的其他问题¶
内核符号unknow¶
实际上我们在分析CPU占用型软件性能时,一般也不需要内核符号,但如果想要看到,那么需要修改kptr_restrict
app的函数行为无法记录¶
现象为最终生成的火焰图只有程序名,没有程序中的函数名。通过熟悉perf record的命令参数,发现-b能够解决此问题
符号被修改¶
现象为最终生成的火焰图符号被修改,通过readelf查看生成的可执行文件,发现符号本身就是被修改的,被困扰了半天之后才明白,这是c++的name mangling机制,用来解决重载问题。 实际上如果对C++理解比较多的人应该都知道这个,我半路出家还真是头一次知道。于是发现c++filt可以有效demangling这些符号,在perf script中加入c++filt即可。
总结¶
这篇记录里大多数的操作都是网上查到的,我只是记录了一下而已。而且perf这个分析方法也是同事告诉我的, 其实我只是一个实施者,但从中应该学到的是如何快速的掌握一个工具使用方法的能力。应该提高的是查资料的能力。
perf 统计cache miss情况¶
perf stat -e L1-dcache-load-misses -e L1-dcache-loads -e LLC-load-misses -e LLC-loads -e LLC-store-misses -e LLC-stores -e dTLB-load-misses -e dTLB-loads -e dTLB-store-misses -e dTLB-stores ./randomstream
统计结果
Performance counter stats for './randomstream':
14,489,916,426 L1-dcache-load-misses # 16.83% of all L1-dcache hits (39.98%)
86,081,655,549 L1-dcache-loads (39.99%)
2,633,551,306 LLC-load-misses # 40.63% of all LL-cache hits (40.01%)
6,482,329,778 LLC-loads (40.02%)
1,730,604,712 LLC-store-misses (20.00%)
3,079,201,774 LLC-stores (20.00%)
244,280,338 dTLB-load-misses # 0.28% of all dTLB cache hits (30.00%)
86,066,948,345 dTLB-loads (40.00%)
1,414,326,484 dTLB-store-misses (39.99%)
45,374,302,611 dTLB-stores (39.98%)
19.019721004 seconds time elapsed
282.336445000 seconds user
818.115020000 seconds sys