gprof 输出不准确

Posted

技术标签:

【中文标题】gprof 输出不准确【英文标题】:Inaccuracy in gprof output 【发布时间】:2011-02-17 11:14:58 【问题描述】:

我正在尝试使用 gprof 分析一个 c++ 函数,我对所花费的时间百分比很感兴趣。我跑了不止一次,由于某种原因,我的结果有很大的不同。我不知道是什么原因造成的,我假设采样率或者我在其他帖子中读到 I/O 与它有关。那么有没有办法让它更准确并以某种方式产生几乎恒定的结果?

我在想以下几点:

    提高采样率 在执行任何操作之前刷新缓存 使用另一个分析器,但我希望它以与 grof 类似的格式生成结果作为函数时间% 函数名称,我尝试了 Valgrind,但它给了我一个很大的文件。所以也许我使用错误的命令生成文件。

等待您的输入

问候

【问题讨论】:

【参考方案1】:

我建议打印一份the gprof paper 并仔细阅读。

根据论文,这是 gprof 测量时间的方式。它对 PC 进行采样,并计算每个例程中有多少样本落入。乘以样本之间的时间,即每个例程的总自身时间

它还通过调用站点在表中记录例程 A 调用例程 B 的次数,假设例程 B 由 -pg 选项检测。通过总结这些,它可以知道例程 B 被调用了多少次。

从调用树的底部开始(其中总时间 = 自身时间),它假定每个例程每次调用的平均时间是其总时间除以调用次数。

然后它会返回到这些例程的每个调用者。每个例程的时间是它的平均自身时间加上每个从属例程的平均调用次数乘以从属例程的平均时间。

您可以看到,即使不存在递归(调用图中的循环),这也充满了错误的可能性,例如关于平均时间和平均调用次数的假设,以及关于被检测的子例程的假设,这作者指出。如果有 递归,他们基本上会说“忘记它”。

所有这些技术,即使没有问题,也引出了一个问题 - 它的目的是什么?通常,目的是“找到瓶颈”。根据该论文,它可以帮助人们评估替代实现。那不是发现瓶颈。他们确实建议查看似乎被多次调用或平均调用次数较高的例程。当然,平均累积时间低的例程应该被忽略,但这并不能很好地定位问题。而且,它完全忽略了 I/O,就好像所有完成的 I/O 毫无疑问都是必要的一样。

因此,要尝试回答您的问题,请尝试Zoom,不要期望消除测量中的统计噪音。

gprof 是一个古老的工具,简单而坚固,但它最初存在的问题仍然存在,并且在随后的几十年中出现了更好的工具。 Here's a list of the issues.

【讨论】:

知道这一点很有帮助。谢谢你。您能否在it completely ignores I/O 上发表更多评论。你的意思是gprof 不采样文件I/O 函数?谢谢。 @WeimingHu:在每个 I/O 操作中,代码必须 A)启动输入或输出过程,因为它在一个单独的处理器,然后 B) 等待,直到输入或输出过程完成。如果流程是输入的,那么直到 B 才真正得到数据。如果流程是输出的,那么直到 B 发生之后,您才能发出下一个 A。在 A 和 B 之间的时间间隔内,您的程序暂停,这就是为什么它无法在那个时间响应gprof 中断。对于某些程序,如果他们只做 I/O,这可能是他们 99.99% 的时间。【参考方案2】:

gprof 不是很准确,特别是小函数,见http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html#SEC11

如果这是 Linux,那么我推荐一个不需要检测代码的分析器,例如Zoom - 您可以获得免费的 30 天评估许可证,之后需要付费。

所有采样分析器都存在统计不准确的问题 - 如果误差太大,那么您需要更长的采样时间和/或更短的采样间隔。

【讨论】:

以上是关于gprof 输出不准确的主要内容,如果未能解决你的问题,请参考以下文章

gprof 输出显示不存在的调用图边缘

gprof 输出问题

使用 gprof 进行奇怪的分析输出

对 gprof 输出感到困惑——调用太多?

为啥循环摘要在 gprof 的调用图输出中没有任何调用者?

如何理解 gprof 输出?