[英]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 )。 事实上, seekg
和tellg
甚至没有在分析列表中,它们是瓶颈!
自我秒是在[无论如何]花费的时间。
累积秒数是[无论]花费的时间和它上面的调用(例如[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不会分析多线程程序。 在这种情况下,最好使用Sysprof或OProfile之类的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.