繁体   English   中英

令人困惑的gprof输出

[英]Confusing gprof output

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

%   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]

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

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

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

瓶颈原来是在文件I / O中(参见Is std :: ifstream明显比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甚至没有在分析列表中,它们是瓶颈!

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

累积秒数是[无论]花费的时间和它上面的调用(例如[whatever] + main)

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

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

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

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

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

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

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

但无论它在哪里, 它花费那段时间的责任由调用堆栈上的每一行代码共同共享 ,因为如果没有进行任何一个这样的调用,它就不会在进行的过程中该电话要求的工作。

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

您是否尝试过此问题中提到的其他一些工具? 他们如何比较会很有趣。

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

你可能想读了有关如何分析gprof的的扁平型材。

更正:对不起,这些前两秒的值是累积的,如OP指出的那样。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM