如何使用Linux的`perf`工具生成“Off-CPU”性能分析报告

19
Brendan D. Gregg(《DTrace书》的作者)提出了一种有趣的分析技术:"Off-CPU" profiling(和Off-CPU Flame Graphslides 2013, p112-137),以查看线程或应用程序在哪里被阻塞(未被CPU执行,但正在等待I/O,页面错误处理程序或由于CPU资源短缺而取消调度):该技术可以显示代码路径在何处被阻塞并等待,以及具体等待多长时间。这与传统的分析技术不同,后者通常只对CPU上正在执行工作的线程进行定期采样,并且仅检查这些线程。
他还可以将Off-CPU概要数据和On-CPU概要数据合并在一起:http://www.brendangregg.com/FlameGraphs/hotcoldflamegraphs.html Gregg给出的示例是使用dtrace创建的,这在Linux操作系统中通常不可用。但是有一些类似的工具(ktap、systemtap、perf),我认为perf的安装基数最广泛。通常,perf生成On-CPU概要文件(哪些函数在CPU上执行得更频繁)。
如何将Gregg的Off-CPU示例转换为Linux中的perf分析工具?

PS:这里有一个指向Off-CPU火焰图的systemtap变体的链接,可以在来自LISA13的幻灯片,p124中找到:“ Yichun Zhang 创建了这些火焰图,并一直在使用它们在Linux上与SystemTap一起收集配置文件数据。请参见:•http://agentzh.org/misc/slides/off-cpu-flame-graphs.pdf“(CloudFlare啤酒会,2013年8月23日)


相关问题 - 使用perf分析睡眠时间:https://dev59.com/n2Ei5IYBdhLWcg3wBYAt - osgx
2个回答

16

我发布的perf技术[1]是一种高开销的解决方案,直到perf具备用于执行此操作的BPF支持。

目前,在支持BPF堆栈跟踪的4.6+内核上(使用bcc/BPF),生成Linux上的CPU外火焰图的最低成本方式。我编写了一个名为offcputime[2]的工具,可以使用“-f”选项运行,并适合用于输入到flamegraph.pl中的"folded output"。这个offcputime工具在内核内容中完成计时和堆栈计数,并且转储一个包含符号的报告。

有一天,我期望perf本身也能够做到这一点:运行一个BPF程序来进行内核计数和报告转储。

与此同时,我们可以使用bcc/BPF。如果由于某些原因无法使用bcc,则现在可以将那个offcputime程序编写为C语言。更复杂的版本可在Linux源代码中找到,位于samples/bpf/offwaketime*中。随着Linux上的新BPF功能,只要有意愿,就有方法。

[1] http://www.brendangregg.com/blog/2015-02-26/linux-perf-off-cpu-flame-graph.html

[2] https://github.com/iovisor/bcc/blob/master/tools/offcputime_example.txt


5
Brendan Gregg发布了有关生成Off-cpu火焰图的说明:http://www.brendangregg.com/blog/2015-02-26/linux-perf-off-cpu-flame-graph.htmlhttps://github.com/brendangregg/FlameGraph/issues/47# “Off-CPU时间火焰图”可以解决60%的问题,其余需要遍历线程唤醒以找到根本原因。我在我的LISA13 flame graph演讲中(幻灯片youtube视频)中解释了Off-CPU时间火焰图、唤醒问题及其他工作。
在这里,我将展示一种使用Linux perf_events进行Off-CPU时间火焰图的方法。
# perf record -e sched:sched_stat_sleep -e sched:sched_switch \
 -e sched:sched_process_exit -a -g -o perf.data.raw sleep 1
# perf inject -v -s -i perf.data.raw -o perf.data
# perf script -f comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace | awk '
NF > 4 { exec = $1; period_ms = int($5 / 1000000) }
NF > 1 && NF <= 4 && period_ms > 0 { print $2 }
NF < 2 && period_ms > 0 { printf "%s\n%d\n\n", exec, period_ms }' | \
./stackcollapse.pl | \
./flamegraph.pl --countname=ms --title="Off-CPU Time Flame Graph" --colors=io > offcpu.svg

使用Gregg的stackcollapse.pl和flamegraph.pl来绘制火焰图。

从3.17内核开始使用perf选项...


不要被漂亮的像素、热情的手势或新的行话词汇,如 on-CPU 和 off-CPU 所吸引。如果你不仅仅是 "分析性能",而是在积极地寻求最大的性能,就必须找到那些试图躲避你的 "瓶颈",它们很容易藏在火焰图中。点击这里查看。 - Mike Dunlavey
2
我想说的是:1)如果加速可以节省X分之一的时间,那么需要进行两次曝光的平均样本数量为2/X,而不是数千个。(Gregg举了一个例子,2000倍加速可以节省0.9995的时间 - 两个或甚至一个 样本就足以证明它。)2)如果采取数千个样本并进行总结(如火焰图或任何其他摘要),则会失去精确告诉您加速比的洞察力,而您不能错过任何一个。3)可能有更好的方法 - 让我们看看它是什么。 - Mike Dunlavey
1
数百万程序员可能会被一种有害的想法感染,即认为寻找加速需要大量的样本进行总结。这个想法没有理论或实践基础。它伤害他们的方式是总结掩盖了实际的加速,而这些加速根本就找不到。有些人并不受群体影响,比如Jon Bentley(幻灯片35页)、Agner Fog(第18页)以及在此处投票的人。 - Mike Dunlavey
PPPS:2000倍加速的例子(我想你指的是http://dtrace.org/blogs/brendan/2011/12/08/2000x-performance-win/)并不是基于新的流行词(on/off cpu),而是基于旧的Sun公司的营销策略——Dtrace;但实际上,问题是通过取样堆栈来确定的。唯一的区别是他使用了2000个样本,因为他可以,并且他有3个不同的堆栈,每个堆栈都指向mbtowc或多字节代码。是的,一个或两个样本就足以解决问题,但这个例子是关于Dtrace营销的(http://www.slideshare.net/brendangregg/from-dtrace-to-linux - 第14张幻灯片“Dtrace had awesome”)。 - osgx
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mike Dunlavey
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接