Linux Oprofile调用图:系统调用的来源
我一直在使用oprofile试图发现为什么我的程序在内核中花费了这么多时间。我现在有了内核中的符号,但显然在我的程序和内核之间没有链接来告诉我程序的哪些部分花费了这么长时间Linux Oprofile调用图:系统调用的来源,linux,profiling,oprofile,Linux,Profiling,Oprofile,我一直在使用oprofile试图发现为什么我的程序在内核中花费了这么多时间。我现在有了内核中的符号,但显然在我的程序和内核之间没有链接来告诉我程序的哪些部分花费了这么长时间 samples % image name app name symbol name ------------------------------------------------------------------------------- 2
samples % image name app name symbol name
-------------------------------------------------------------------------------
201 0.8911 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic _raw_spin_lock_irq
746 3.3073 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic rb_get_reader_page
5000 22.1671 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic default_spin_lock_flags
16575 73.4838 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic _raw_spin_lock
22469 11.1862 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic __ticket_spin_lock
22469 99.6010 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic __ticket_spin_lock [self]
26 0.1153 vmlinux-3.0.0-30-generic vmlinux-3.0.0-30-generic ret_from_intr
我该怎么办?如何在程序中发现导致“票证旋转锁定”的位置?Oprofile获取堆栈样本。您需要做的不是查看它们的摘要,而是实际检查原始样本。如果你花了,比如说,30%的时间在内核中,那么如果你能看到随机选择的10个堆栈样本,你可以期望其中的3个,或多或少,向你展示你进入内核的全部原因 摘要或调用图不会显示给您 如果不清楚:由于
\u ticket\u spin\u lock
99.6%的时间在堆栈上,那么在您查看的每个堆栈样本上,概率为99.6%,您将看到如何进入该例程。
然后,如果你真的不需要这样做,你可能有一个250倍的加速。
从四分钟减到一秒钟。用“正确的”或“自动的”方法——得到结果
补充:剖析器的特点是它们很受欢迎,有些具有非常好的UI,
但遗憾的是,恐怕这是“皇帝的新衣”的例子。
如果这样一个工具没有发现太多需要修复的地方,你会喜欢它的,因为它说(可能是错误的)你的代码在编写时接近最优
有很多帖子推荐这个或那个剖析器,但是
我不能指出任何使用分析器节省超过百分之几时间的说法,比如40%。
也许有一些
我从来没有听说过一个分析器先被用来获得加速,然后再被用来获得第二个加速,依此类推。
这就是如何获得真正的加速-多重优化。
一开始只是一个小的性能问题,但在删除了一个更大的问题后,它就不再是小问题了。
这张图片显示了如何通过消除六个问题,加速率接近三个数量级。
你不一定能做到,但这不值得一试吗
对进一步编辑表示歉意。我只是想让大家明白,愚弄一个调用图是很容易的。
红线表示调用堆栈示例。在这里,A1将所有时间都花在呼叫C2上,反之亦然。然后假设您保持相同的行为,但是您加入了一个“分派”例程B。
现在调用图会丢失A1在C2中花费的所有时间的信息,反之亦然。
您可以轻松地将此示例扩展到多个级别。
你可以说呼叫树会看到这一点。
好吧,下面是你如何愚弄呼叫树的方法。A把所有的时间都花在给C打电话上。
现在如果A调用B1,B2。。。Bn,那些称为C的,从A到C的“热路径”被分解成碎片,因此A和C之间的关系被隐藏。
还有许多其他非常普通的编程实践会混淆这些工具,特别是当示例深度为10-30级且函数都很小时,但是,如果程序员仔细检查中等数量的样本,就无法隐藏这种关系。我同意迈克的回答:调用图不是检查问题根源的正确方法。您真正想要的是查看最热门样本的调用链
如果不想“手动”检查oprofile采集的原始样本,可以使用-g选项的
record
命令重新运行应用程序,以采集stacktraces。然后,您可以使用perf的report
命令显示带注释的样本。由于perf没有在全局调用图中聚合单个样本的调用链,因此您没有Mike帖子中概述的一些问题。您是否使用了--callgraph
选项?--callgraph=10
onopcontrol
和opreport
有趣的帖子,谢谢。有没有办法使用我在oprofile中收集的数据?这似乎有点过于手工,不是“正确”的方法。对吗?太手工了?超过500张的选票不在那里,因为它是不正确的。如果您追溯性能评测背后的想法来自何处,那么它们是没有根据的。它们基于测量的整体概念。奥托,如果你有一个无限循环,你不能通过测量找到它,是吗?不可以。您将其视为一个要手动发现的bug,并在调试器中停止它。好的,当一个程序花费的时间超过它所能花费的时间时,同样的技术是最好的。你们随机抽取时间样本,仔细检查。@MikeDunlavey:是的。首先,oprofile
使用统计抽样,这相当于您建议的方法(尽管它需要较少的手动干预,并且在无法停止程序的情况下有效)。在这种特殊情况下,建议筛选大量样本是不可行的。我可能会建议检查这里的调用图设置,因为它们似乎被截断了,或者使用opreport
--contracted选项,或者将结果限制在要分析的图像上,使用这些来识别有问题的调用链。@Hasturkun:1)采样是可以的,但对它们所做的事情不是。2) 问题很容易隐藏在调用图中,比如它取决于调用发生的数据或代码行。3) 为什么需要大量样本是毫无根据的。4) 的第3点显示了调用图的问题。5) 使用任何分析器,您听说过哪些加速因子?我不是说没有。我是说它们很小。@MikeDunlavey:Re:2,在大多数情况下,这仍然会给您一个代码区域来关注(另外,IIRC,调度例程案例不应该丢失信息。虽然我现在无法验证这一点,但我想oprofile会给您关于调用的指令级详细信息)。在任何情况下,都应检查配置文件输出,