火焰图的某一个函数越宽,不代表这个函数执行的慢,而是表示这个函数被采样到的次数比较多,程序指令流经常执行到这个函数,所以宽度其实表示的是执行的频繁程度。因此优化这个函数更能提升程序整体的性能。

如何抓取火焰图 flame graph?

根据这里的教程(pid 为 181,采集时间 60s,采样频率为 99hz):

perf record -F 99 -p 151262 -g -- sleep 3600
# 把 perf.data 二进制格式转成 out.perf 文本文件格式
# -g: call graph
perf script > out.perf

git clone https://github.com/brendangregg/FlameGraph
cd FlameGraph
chmod +x stackcollapse-perf.pl
# 转成 folded 文件
./stackcollapse-perf.pl out.perf > out.folded

# 下载这个脚本文件
cd FlameGraph
./flamegraph.pl out.folded > kernel.svg

brendangregg/FlameGraph: Stack trace visualizer

火焰图只抓内核态函数

也是可以抓到第一层用户态的函数的,可以用来分析什么时候内核态运行比较多什么时候是用户态运行比较多。

sudo perf record -F 99 -p 99402 -g --kernel-callchains -- sleep 3600

火焰图的横轴就是时间吗,如果进程在睡眠会怎么记录?

注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。 这点很重要!

进程睡眠的时间不会记录在里面。因为只记录在 running 的时候跑在了什么函数比较多。进程睡眠时 cycles 会停或者记录下来的是其他进程的时间,不会归属到这个进程的 call chain 里。

performance - Flame graph(perf record) cannot display accurate CPU idle usage - Stack Overflow