Linux系统性能分析工具--Perf
一、perf工具介绍
perf 命令(performance 的缩写),是Linux系统提供的性能分析工具集,包含多种子工具,能够监测多种硬件及软件性能指标,包括cpu、内存、io等,这些可监测指标我们称为event。
Brendan Gregg的文章中总结了perf 支持的event结构图,详情可见:
perf event结构图
二、perf工作模式
2.1 计数模式
记录perf执行过程中event的出现次数。
2.2 采样模式
在perf执行过程中,按照指定频率去采样event,每次采样时,记录当前性能指标信息(cpu、进程id、运行栈等)。这种方式由于每次都记录信息,所以额外的资源消耗是比较大的,需要权衡一下采样频率。
2.3 自定义模式
可以对对应的event执行用户自己设计的代码,也就是说记录的信息、执行的操作可以由用户定制。
三、perf安装
对于ubuntu等linux系统发行版,都提供了对应的包,只要根据内核版本进行安装即可。安装的命令如下:
# 在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
四、perf使用方法
4.1 perf list
perf list查看当前系统支持的性能事件。
4.2 perf top
perf top类似top命令,主要用于实时分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数、模块函数与内核函数,甚至能够定位到热点指令。执行需要root权限。
Perf top:实时显示系统/进程的性能统计信息
常用参数
-e:指定性能事件 -a:显示在所有CPU上的性能统计信息
-C:显示在指定CPU上的性能统计信息 -p:指定进程PID
-t:指定线程TID -K:隐藏内核统计信息
-U:隐藏用户空间的统计信息 -s:指定待解析的符号信息
‘-G’ or‘--call-graph’ <output_type,min_percent,call_order>
graph: 使用调用树,将每条调用路径进一步折叠。这种显示方式更加直观。每条调用路径的采样率为绝对值。也就是该条路径占整个采样域的比率。
fractal:默认选项。类似与 graph,但是每条路径前的采样率为相对值。
flat: 不折叠各条调用
选项 call_order 用以设定调用图谱的显示顺序,该选项有 2个取值,分别是callee 与caller。
将该选项设为callee 时,perf按照被调用的顺序显示调用图谱,上层函数被下层函数所调用。
该选项被设为caller 时,按照调用顺序显示调用图谱,即上层函数调用了下层函数路径,也不显示每条调用路径的采样率
4.3 perf stat
perf stat用于统计event出现的次数,我们还是先运行前面的测试代码,再简单运行一下perf stat看看:
4.4 perf record
perf record是采样模式,perf收集采样信息并记录在文件中,可以离线分析。使用下面的 perf report解析收集的采样数据文件。
Perf record:记录一段时间内系统/进程的性能参数
参数:
-e:选择性能事件 -p:待分析进程的id
-t:待分析线程的id -a:分析整个系统的性能
-C:只采集指定CPU数据 -F:采样频率,每秒多少次
-c:事件的采样周期 -o:指定输出文件,默认为perf.data
-A:以append的方式写输出文件 -f:以OverWrite的方式写输出文件
-g:记录函数间的调用关系
举例:
sudo perf record -e cpu-clock -g -p 2548
-g 选项是告诉perf record额外记录函数的调用关系
-e cpu-clock 指perf record监控的指标为cpu周期
-p 指定需要record的进程pid
采样一段时间,可以使用ctrl+c停止命令,这时会生成 perf.data 文件(默认文件名)
4.5 perf report
perf report 主要用来分析上面perf record生成的perf.data文件。
perf report:读取perf record生成的数据文件,并显示分析数据
参数
-i:输入的数据文件 -v:显示每个符号的地址
-d <dos>:只显示指定dos的符号 -C:只显示指定comm的信息(Comm. 触发事件的进程名)
-S:只考虑指定符号 -U:只显示已解析的符号
-g[type,min,order]:显示调用关系 -c:只显示指定cpu采样信息
-M:以指定汇编指令风格显示 –source:以汇编和source的形式进行显示
-p<regex>:用指定正则表达式过滤调用函数
举例: sudo perf report -n --stdio :统计每个调用栈出现的百分比,然后从高到低排列。
可以看到,通过perf report分析得到的结果不直观,可读性比较差,所以才有了火焰图。
五 火焰图 Flame Graph
下载方式:
1、手动下载:Flame Graph项目位于GitHub上:https://github.com/brendangregg/FlameGraph
2、可以用git将其clone下来:git clone https://github.com/brendangregg/FlameGraph.git
5.1 ON-CPU火焰图
on-cpu火焰图可以用于分析cpu是被哪些线程、哪些函数占用的,可以方便的找到热点代码便于后续分析优化。
生成火焰图的操作步骤如下:
第一步: 采样并记录性能数据
$sudo perf record -e cpu-clock -g -p 28591
// Ctrl+c结束执行后,在当前目录下会生成采样数据perf.data.
第二步:用perf script工具对perf.data进行解析
perf script -i perf.data &> perf.unfold
第三步:将perf.unfold中的符号进行折叠
./stackcollapse-perf.pl perf.unfold &> perf.folded
第四步:生成svg文件
./flamegraph.pl perf.folded > perf.svg
5.2 OFF-CPU火焰图
对于IO消耗型的任务,on-cpu并不能捕获任务大部分的时间去了哪里,配合上off-cpu的统计则可以让我们更清楚的看到任务运行时间的分布,所以off-cpu火焰图用于显示非cpu耗时的问题:
1、进程进入系统调用执行io动作,io动作的延迟;
2、进程等待mutex锁的时间
3、内存被交换,swap的时间
4、内存不够的时候,执行直接内存回收的时间
5、进程被抢占调度走、或者时间片用完被调度走的时间(runqueue太大)
// 安装off-cpu 数据获取工具
#apt install bpfcc-tools
// 截取a.out30秒offcpu 耗时分析的栈数据
sudo offcputime-bpfcc -df -p `pgrep -nx a.out` 30 > out.stacks
// 转化为火焰图
./flamegraph.pl --color=io --title="Off-CPU Time Flame Graph" --countname=us ~/out.stacks > output.svg
5.3 红蓝差分火焰图
在代码优化后,还可以使用FlameGraph工具生成红蓝差分火焰图观察优化效果。前面优化前后的采样中生成了两个.floded,对其进行对比并绘制成图。
# stackcollapse-perf.pl perf.script > workrun.floded # 优化前数据
# stackcollapse-perf.pl perf.script > workrun_2.floded # 优化后数据
# difffolded.pl workrun.floded workrun_2.floded > diff.floded # 获取差异数据
flamegraph.pl diff.floded > diff.svg #绘图
diff.svg即为优化前后的红/蓝差分火焰图,图中使用不同的颜色来表示两个文件中的差异部分。红色表示增长, 蓝色表示衰减,并带有百分比。(这里随便贴一张图)
5.4 解析火焰图
火焰图是基于 stack 信息生成的 SVG 图片, 用来展示 CPU 的调用栈。
火焰图中的每一个方框是一个函数,方框的长度,代表了它的执行时间,所以越宽的函数,执行越久。火焰图的楼层每高一层,就是更深一级的函数被调用,最顶层的函数,是叶子函数。
y 轴表示调用栈, 每一层都是一个函数. 调用栈越深, 火焰就越高, 顶部就是正在执行的函数, 下方都是它的父函数。x 轴表示抽样数, 如果一个函数在 x 轴占据的宽度越宽, 就表示它被抽到的次数多, 即执行的时间长. 注意, x 轴不代表时间, 而是所有的调用栈合并后, 按字母顺序排列的。
火焰图就是看顶层的哪个函数占据的宽度最大. 只要有 “平顶”(plateaus), 就表示该函数可能存在性能问题。颜色没有特殊含义, 因为火焰图表示的是 CPU 的繁忙程度, 所以一般选择暖色调.
火焰图是 SVG 图片, 可以与用户互动.
鼠标悬浮:火焰的每一层都会标注函数名, 鼠标悬浮时会显示完整的函数名、抽样抽中的次数、占据总抽样次数的百分比
点击放大:在某一层点击,火焰图会水平放大,该层会占据所有宽度,显示详细信息。
左上角会同时显示 “Reset Zoom”, 点击该链接, 图片就会恢复原样.
搜索:按下 Ctrl + F 会显示一个搜索框,用户可以输入关键词或正则表达式,符合条件的函数名会高亮显示。