目录

Linux下应用火焰图(Flame Graph)可视化交互程序剖析


目录

确定CPU繁忙的原因是性能分析的一项常规任务,这通常涉及到对堆栈跟踪的剖析。通过固定速率的采样进行剖析是一种粗略但有效的方法,可以看到哪些代码路径是热的(CPU上的繁忙)。它通常通过创建一个定时中断来收集当前的程序计数器、函数地址或整个堆栈回溯,并在打印总结报告时将其转化为人类可读的东西。

linux-tools中的系统级性能分析工具perf提供一个性能分析框架,通过perf,应用程序可以利用PMU、tracepoint和内核中的计数器来进行性能统计。tracepoints是散落在内核源码中的一些hook,它们可以在特定的代码被执行到时触发,这一特点可以被各种trace/debug工具所使用。perf将tracepoint产生的时间记录下来,生成报告,通过分析这些报告,调优人员便可以了解程序运行期间内核的各种细节,定位程序的性能瓶颈。

然而,perf生成的剖析数据可能有几千行之长,人类是视觉动物,在阅读大量的数字和理解它们方面相当糟糕。火焰图(Flame Graph)是采样堆栈跟踪的一种可视化方式。除CPU剖析外,这种可视化的用途见火焰图的主页。

在这里,我将介绍如何使用Flame Graph生成程序剖析的CPU火焰图,它可以配合perf使用,并且生成的SVG是交互式的,可以放大或搜索定位到程序的特定部分,其效果如下:

https://www.brendangregg.com/FlameGraphs/cpu-mysql-updated.svg

安装

首先安装perf,以Arch Linux为例:

1
sudo pacman -S perf

拉取FlameGraph仓库

1
git clone https://github.com/brendangregg/FlameGraph  # or download it from github

使用

1
2
cd FlameGraph
sudo perf record -F 99 -a -g -- COMMAND [ARGS]

COMMAND [ARGS]为你要剖析的程序及参数,该命令参数的含义是栈帧采样率为99Hz(-F 99),记录所有CPU核心的事件(-a),对内核空间和用户空间启动函数调用图记录功能(-g)。除此之外,其它常用的参数如下:

  • -p, --pid=:记录指定pid进程的事件,可用逗号分隔多个进程pid
  • -e, --event=:选择指定的PMU事件
  • -C, --cpu:仅在指定CPU核心上采样。如0,1 0-2
  • -o, --output=:输出文件名

程序执行完毕后,当前目录下生成perf.data剖析数据。我们将使用FlameGraph仓库中的脚本生成火焰图:

1
2
sudo perf script | ~/FlameGraph/stackcollapse-perf.pl > out.perf-folded
~/FlameGraph/flamegraph.pl out.perf-folded > perf.svg

当前目录下生成perf.svg。用浏览器打开(Firefox为例):

1
firefox perf.svg

你可以通过鼠标点击来探索火焰图,或者通过右上角的搜索功能定位到某处。

参考

CPU Flame Graphs

Debugging and Profiling - the missing semester of your cs education