如何分析程序运行时间

7

我正在尝试优化一个C++程序的性能并减少其运行时间。然而,我很难弄清楚瓶颈在哪里。

time命令显示程序本身运行大约需要5分钟,其中用户CPU时间占用了4.5分钟。

CPU分析器(包括gcc分析器和google perftool)显示函数调用总共只占用60秒的CPU时间。我还尝试使用分析器对实际时间进行采样,结果与CPU时间类似。

I/O分析器(我使用ioapps)也显示I/O只占用程序运行时间的大约30秒。

因此基本上有3.5分钟(程序运行时间最长的部分)无法解释,我认为这就是瓶颈所在。

我错过了什么,如何知道时间去了哪里?


1
根据你提供的信息,我的最佳猜测是你没有正确地阅读分析器的输出。请发布gprof/perf/strace的输出(至少前15行)。 - DanielKO
1
你能不能在调试器中多次中断程序,看看它出问题的地方?通常大部分时间都耗费在那里。 - Öö Tiib
1
我读对了吗?find_first_zero()被调用了 24.8 亿次? - WhozCraig
1
是的,但这个函数已经高度优化并且内联了。它只需要4秒钟就能运行,而我更关心的是那4分钟。 - yangsuli
1
你能否在帖子中附上你的代码? - superK
显示剩余3条评论
1个回答

8
正如Öö Tiib所建议的那样,在调试器中断程序。我的做法是先让程序运行,然后切换到输出窗口,按Ctrl-C中断程序,再切换回GDB窗口,输入“thread 1”以进入主程序上下文,然后输入“bt”查看堆栈跟踪。
现在,看看堆栈跟踪并理解它,因为尽管程序计数器上的指令负责该特定周期的消耗,但是每个堆栈调用也是如此。
如果您这样做几次,就会看到哪一行代码导致瓶颈。 只要在两个(2)样本中看到它,您就找到了它。 然后修复它,重新开始,找到下一个瓶颈,以此类推。 您可以很容易地通过这种方式获得巨大的加速。
有些人说这正是分析工具所做的,只不过它们做得更好。 这是您在讲堂和博客上听到的,但是事实是: 有些提高代码速度的方法不会表现为“慢函数”或“热点路径”,例如重新组织数据结构。 即使某个函数具有高包含时间百分比,它看起来也基本无罪。
如果你确实查看堆栈样本,它们会自己显露出来。因此,好的分析器的问题不在于样本的收集,而在于结果的呈现。统计数据和测量结果无法告诉你仔细检查的一小部分样本所能告诉你的信息。
那么样本数量的大小问题呢?更多的样本难道不是更好吗?假设你有一个无限循环,或者即使不是无限循环,运行时间也比你知道的要长得多怎么办?1000个堆栈样本是否比单个样本更好地找到它?(不是)如果你在调试器下查看它,你知道你在循环中,因为它基本上占用了100%的时间。它在堆栈的某个地方 - 只需向上扫描堆栈,直到找到它。即使循环只占用50%或20%的时间,每个样本都有可能看到它。因此,如果你在两个样本中看到了可以消除的东西,那么这是值得做的事情。那么,1000个样本对你有什么帮助呢?
也许有人会想:“如果我们错过一两个问题又怎样?也许这已经足够好了。” 那么,真的吗?假设代码存在三个问题 P,占用50%的时间,Q占用25%,R占用12.5%。好的部分称为A。下面展示了您解决其中一个问题、两个问题或全部三个问题所获得的加速比。
PRPQPQPAPQPAPRPQ original time with avoidable code P, Q, and R all mixed together
RQQAQARQ         fix P           - 2 x   speedup
PRPPPAPPAPRP     fix Q           - 1.3 x    "
PPQPQPAPQPAPPQ   fix R           - 1.14 x   "
RAAR             fix P and Q     - 4 x      "
QQAQAQ           fix P and R     - 2.7 x    "
PPPPAPPAPP       fix Q and R     - 1.6 x    "
AA               fix P, Q, and R - 8 x   speedup

这就是为什么那些“逃脱”的问题会真正伤害你的原因吗?如果你错过任何一个,最好的办法是慢两倍。
如果检查样本,它们很容易找到。P 在一半的样本中。如果你修复 P 并再次运行,Q 就在一半的样本中。一旦你确定了 Q,R 就在一半的样本中。修复 R,然后你就可以得到 8 倍的加速。你不必停止。你可以继续下去,直到你真的找不到需要修复的内容为止。
问题越多,潜在的加速比就越高,但你不能错过任何一个。性能分析器的问题(即使是好的性能分析器)是,通过拒绝让你看到和研究单个样本,他们隐藏了你需要找到的问题。更多信息。对于统计倾向者,这里是它的工作原理。

有很好的分析工具。 最好的是 wall-time stack samplers,可以报告每行的包含百分比,并让你通过热键打开和关闭采样。 Zoom (wiki) 就是这样一个分析工具。

但即使是这些工具也会犯错误,认为你需要大量的样本。 实际上不需要,付出的代价是你实际上看不到任何东西,所以你不能看到时间被花在了哪里,因此你不能轻易地判断它是否必要, 除非你知道你不需要它,否则你无法摆脱它。 结果是你错过了瓶颈,它们最终会阻碍你的速度提升。

</flame>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接