如何分析程序运行时间
How to analyze program running time
我正在努力优化c++程序的性能并减少其运行时间。然而,我很难弄清楚瓶颈在哪里。
time命令显示程序本身运行大约需要5分钟,用户cpu时间大约需要4.5分钟。
CPU探查器(gcc探查器和googleperftool)显示,函数调用总共只需要60秒的CPU时间。我还尝试使用探查器来实时采样,而不是cpu时间,它给了我类似的结果。
I/O探查器(我使用过ioapps)还显示,I/O只需要大约30秒的程序运行时间。
因此,基本上我有3.5分钟(程序运行时间的最大部分)没有计算在内,我相信这就是瓶颈所在
我错过了什么?我如何知道那段时间会去哪里?
正如ÖTiib所建议的,只需在调试器中中断程序即可。我这样做的方法是让程序运行,切换到输出窗口,键入Ctrl-C来中断程序,切换回GDB窗口,键入"thread 1"以便在主程序的上下文中,然后键入"bt"来查看堆栈跟踪。
现在,看看堆栈跟踪并理解它,因为虽然程序计数器上的指令负责所花费的特定周期,但堆栈上的每个调用也是如此。
如果你这样做几次,你就会确切地看到是哪条线造成了瓶颈。一旦你在两(2)个样本上看到它,你就已经把它钉住了。然后修复它,然后再做一遍,找到下一个瓶颈,以此类推。你可以很容易地发现,你可以通过这种方式获得巨大的加速。
<火焰>
有些人说,这正是剖析者所做的,只是他们做得更好。这是你在演讲厅和博客上听到的,但交易如下:有一些方法可以加快代码的速度,而不会显示为"慢函数"或"热路径",例如,重新组织数据结构。每个函数看起来或多或少都是无辜的,即使它有很高的包含时间百分比。
如果您实际查看堆栈样本,它们确实会显示自己。因此,好的轮廓仪的问题不在于样本的收集,而在于结果的呈现。统计和测量无法告诉你,经过仔细检查的一小部分样本确实告诉了你什么。
样本数量少与样本数量大的问题如何?不是更好吗?好吧,假设你有一个无限循环,或者如果不是无限的,它只是运行的时间比你知道的要长得多?1000个堆叠样本会比单个样本更好吗?(不是。)如果你在调试器下看它,你就会知道你在循环中,因为它基本上需要100%的时间。它在堆栈的某个地方——只需向上扫描堆栈,直到找到它。即使循环只需要50%或20%的时间,这也是每个样本看到它的概率。所以,如果你在两个样本上看到了可以去除的东西,那么这是值得的。那么,1000个样品给你买了什么?
也许有人会想:"如果我们错过了一两个问题怎么办?也许这已经足够好了。"好吧,是吗?假设代码有三个问题,P占用50%的时间,Q占用25%的时间,R占用12.5%的时间。这显示了如果你修复其中一个、两个或全部三个,你会得到加速。
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倍的加速。你不必就此止步。你可以一直坚持下去,直到你真的找不到任何可以解决的问题。
问题越多,潜在的加速就越高,但你不能错过任何一个。评测器(即使是好的评测器)的问题是,通过剥夺你查看和研究单个样本的机会,它们隐藏了你需要发现的问题。更多内容对于有统计学倾向的人来说,以下是它的工作原理
有很好的剖析者。最好的是壁时堆栈采样器,它可以报告单个行的包含百分比,让您可以通过热键打开和关闭采样。Zoom(wiki)就是这样一个探查器。
但即使是那些人也会错误地认为你需要大量的样本。你没有,而你为它们付出的代价是你实际上看不到任何东西,所以你看不到为什么要花时间,所以你无法轻易判断是否有必要,除非你知道自己不需要它,否则你无法摆脱它。结果是你错过了瓶颈,它们最终阻碍了你的加速。
<火焰>
- 如何通过cpp程序运行shell脚本
- 用时钟测量程序的运行时间
- 我的 c++ 应用程序中的运行时间从 0 增加到 60 太快了(例如一毫秒或一微秒)
- 如何执行用 C++ 编写的程序的运行时间?
- 如何优化C++键值程序以获得更快的运行时间
- 同一程序的运行时间差异很大,有时达到1000+us
- 测量 OpenCL 应用程序的运行时间
- 如何修复数据库连接的C 程序运行时间错误(0xc0000005)
- 如何在以下C程序中计算运行时间内存和最大数据存储器使用情况
- 使用Clock()函数测量程序的运行时间
- 测量 C++ 多线程程序中的运行时间
- 运行时间错误:程序跳过提示,以获取第二名和第三个名称
- 将一个大文件加载到内存中并在程序的所有运行时间内保持它是错误的
- 为什么我的C++程序使用的系统时间比运行时间多
- 与linux相比,cygwin中的c++程序运行时间较长
- 如何分析程序运行时间
- 计算并行程序的运行时间和cpu时间
- LoadBitmap在程序运行一段时间后返回NULL
- 使用 Unix 程序时间计算每次迭代的程序运行时间
- 查找c++中程序的运行时间