令人困惑的gprof输出

时间:2009-01-27 22:33:28

标签: c++ optimization profiling gprof

根据gprof,我在16.637s的C ++程序上运行了time(),我得到了第一行输出:

%   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
31.07      0.32     0.32  5498021     0.00     0.00  [whatever]

如果只花了31.07%秒,为什么会列出.32的时间?这是一次通话时间吗? (这不是自我/电话吗?)

这是我第一次使用gprof,所以请善待:)

编辑:通过向下滚动,似乎gprof认为我的程序需要1.03秒。为什么会这么错呢?

6 个答案:

答案 0 :(得分:8)

瓶颈原来是在文件I / O中(见Is std::ifstream significantly slower than FILE?)。我切换到在缓冲区中读取整个文件,它加速了。

这里的问题是gprof在等待文件I / O时似乎没有生成准确的分析(参见http://www.regatta.cs.msu.su/doc/usr/share/man/info/ru_RU/a_doc_lib/cmds/aixcmds2/gprof.htm)。事实上,seekgtellg甚至没有在分析列表中,它们是瓶颈!

答案 1 :(得分:6)

自我秒数是在[无论如何]花费的时间。

累积秒数<​​/ strong>是在[无论]及其上方的调用所花费的时间(例如[whatever] + main)

这些都不包括在[无论如何]调用的函数中花费的时间。这就是为什么你没有看到更多时间列出的原因。

例如,如果你的[what]函数调用了很多printf,你的gprof输出会告诉你printf大部分时间都在吃。

答案 2 :(得分:2)

这似乎是how to read gprof output的一个非常好的概述。您正在查看的31.07%是gprof认为仅在该函数中花费的总运行时间的一部分(不包括它调用的函数)。赔率是百分比如此之大的原因,而时间很短是因为gprof认为程序不会像你那样长。通过向下滚动gprof输出的第一部分可以很容易地检查这一点:累积秒数会越来越大,直到它限制程序的总运行时间(从gprof的角度来看)。我想你会发现这只是一秒而不是你所期待的16秒。

至于为什么那里存在如此大的差异,我不能说。也许gprof没有看到所有的代码。或者,在分析时,您是否在仪表代码上使用了时间?我不希望它能正常工作......

答案 3 :(得分:1)

您是否尝试过this question中提到的其他一些工具?他们比较的方式会很有趣。

答案 4 :(得分:1)

您遇到了 gprof 和基于相同概念的其他分析器常见的问题 - 1)对程序计数器进行采样以获得某种直方图,2)检测测量时间的函数,计数,并获得一个调用图。

对于实际定位性能问题,他们忽略了这一点 它不是关于测量例程,而是关于找到有罪的代码。

假设您有一个采样器,可以在随机的挂钟时间内对该程序进行频闪X射线扫描。在每个示例中,程序可能在I / O的中间,它可能在您编译的代码中,它可能在某些库例程中,如 malloc

但无论它在哪里,the responsibility for it spending that slice of time is jointly shared by every line of code on the call stack,因为如果没有进行任何一次这样的呼叫,它就不会执行该呼叫所要求的工作。

因此,请查看显示在调用堆栈的多个样本上的每行代码(它所使用的样本越多越好)。这就是钱的所在。不要只看程序计数器的位置。堆叠上方有“深口袋”。

答案 5 :(得分:0)

是的,那些“秒”值 不是每次通话。百分比时间用于整个程序运行。实际上,你的程序在该功能中花费了31%的时间(由于通话次数+每次通话所花费的时间)。

您可能希望read up了解如何分析gprof的平面轮廓。

更正:很抱歉,前两个值是累积的,如OP指出的那样。

我认为你看到0为“自我”和“总s /电话”是奇怪的。

引用gprof accuracy上的部分:“实际误差量通常超过一个采样周期。事实上,如果一个值是采样周期的n倍,则其中的预期误差是平方根n个采样周期。如果采样周期为0.01秒,foo的运行时间为1秒,则foo运行时的预期误差为0.1秒。从一次性能分析到下一次运行,平均值可能会有很大差异。 (有时它会变化很多。)“

此外,可能相关,值得注意的是gprof不会分析多线程程序。在这种情况下,您最好使用SysprofOProfile之类的内容。