性能测试——火焰图


性能测试——火焰图

0. perf 简介

Perf 是一个用于访问处理器性能监视单元 (PMU) 以及记录和显示软件事件(例如页错误)的界面。它支持系统范围的监视、按线程的监视和 KVM 虚拟化 Guest 监视。

可以在报告中储存生成的信息。例如,此报告包含有关指令指针的信息,或线程执行的代码的信息。

Perf 由两部分组成:

  • 集成到 Linux 内核的代码,负责向硬件发出指令。
  • perf 用户空间实用程序,可让您使用内核代码并帮助您分析收集的数据。

1. 安装 perf

cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

sudo yum install perf
...

2. perf 的使用

2.1 perf 分析流程

Perf 进行性能分析的方式通常有两种:

  • 使用 perf stat 等命令对特定的事件计数器进行计算,并在程序结束后打印数值
  • 使用 perf record 等命令以若干的事件为触发间隔对系统进行采样,将数据保存至 perf.data 文件以供后续分析
  • 也就是说,perf stat 命令只能记录事件发生的次数,perf record 在此基础之上可以记录事件发生时详细的数据(比如 IP、堆栈等等)。

perf record 流程图:

perf record 流程图

在虚拟机上演示:

perf stat ls

 Performance counter stats for 'ls':

          1.643793      task-clock (msec)         #    0.750 CPUs utilized
                 0      context-switches          #    0.000 K/sec
                 0      cpu-migrations            #    0.000 K/sec
               265      page-faults               #    0.161 M/sec
   <not supported>      cycles
   <not supported>      instructions
   <not supported>      branches
   <not supported>      branch-misses

       0.002190790 seconds time elapsed

perf record ls
perf.data
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.016 MB perf.data (7 samples) ]

2.2 perf 事件支持

通过 perf list 可以查看当前支持的所有时间包括硬件事件、软件事件、硬件cache事件、PMU事件以及预设Tracepoint事件

perf list

2.3 perf stat(统计特定类型的事件)

要统计某个事件(例如 perf list 显示的事件)的发生次数,请使用:

perf stat -e EVENT -a

要一次性统计多种类型的事件,请列出这些事件并以逗号分隔。例如,要统计 cpu-cycles 和 instructions,请使用:

perf stat -e cpu-cycles,instructions -a

要停止会话,请按 Ctrl+C。

还可以统计某个事件在特定时间范围内发生的次数:

perf stat -e EVENT -a -- sleep TIME

请将 TIME 替换为以秒为单位的值。

2.4 perf record(记录特定于特定命令的事件)

1、可通过各种方式来对特定于特定命令的事件采样:

1)要创建新调用的命令的报告,请使用:

perf record COMMAND

然后正常使用启动的进程。退出该进程时,Perf 会话也会停止。

2)要在运行新调用的命令时创建整个系统的报告,请使用:

perf record -a COMMAND

3)要创建已运行的进程的报告,请使用:

perf record -p PID

请将 PID 替换为进程 ID。要停止会话,请按 Ctrl–C。

2、现在,可使用以下命令查看收集到的数据 (perf.data):

perf report

这会打开一个伪图形界面。要获得帮助,请按 H。要退出,请按 Q。

3、如果您偏向于使用图形界面,请尝试 Perf 的 GTK+ 界面:

perf report --gtk

但请注意,GTK+ 界面的功能很有限。

火焰图

火焰图是用图形化的方式来展现perf等工具采集的性能数据,对数据进行统计和分析,方便找出性能热点。

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

GitHub 项目:FlameGraph 主页有生成火焰图的详细说明。

克隆项目:

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

FlameGraph list

一个实例:

1.st 生成 perf.data

perf record -F 99 -a -g -- sleep 60 

上述代码中 perf record 表示记录,
-F 99 表示每秒99次,
-p 13204 是进程号,即对哪个进程进行分析,
-g 表示记录调用栈,
sleep 30 则是持续30秒,-a 表示记录所有cpu调用。更多参数可以执行

这条指令的意思是,对CPU所有进程以 99Hz 采集,它的执行频率是 99Hz(每秒99次),如果 99 次都返回同一个函数名,那就说明 CPU 这一秒钟都在执行同一个函数,可能存在性能问题。执行60秒后会弹出如下图提示表示采集完成,在当前目录会生成一个perf.data的文件。

perf.data 文件生成后,表示采集完成。最好是在火焰图的目录下进行采集,方便转换成SVG图形。

2.st 生成火焰图

//生成脚本文件
perf script -i perf.data &> perf.unfold

//生成火炬图
./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg

执行完成后生成 perf.svg 图片,可以下载到本地,用浏览器打开 perf.svg,如下图

perf.svg

火焰图的含义

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

perf_5.svg

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

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

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

颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

差分火焰图

# 第一次Profiling结果
perf record -ag -F 999 -- sleep 20
perf script -i perf.data &> A.stacks
# 第二次Profiling结果
perf record -ag -F 999 -- sleep 20
perf script -i perf.data &> B.stacks
# 下载FlameGraph仓库
git clone --depth 1 http://github.com/brendangregg/FlameGraph 
# 折叠A.stacks和B.stacks
./FlameGraph/stackcollapse-perf.pl A.stacks &> A.folded
./FlameGraph/stackcollapse-perf.pl B.stacks &> B.folded
# 基于折叠结果做差
./FlameGraph/difffolded.pl A.folded B.folded > diff.folded
# 生成差分火焰图
./FlameGraph/flamegraph.pl diff.folded > diff.svg

参考资料:


文章作者: Pudding
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Pudding !
  目录