3

我的应用程序性能存在一些问题。我在 Stackoverflow 上找到了这个答案: https ://stackoverflow.com/a/378024/5363

我喜欢。我不太明白的一点是代码优化和分析之间的关系是什么。因为显然人们想要分析优化的代码,但同时在优化过程中会丢失很多信息。那么在调试器中运行优化代码并按照引用的答案中的建议闯入它是否可行?

我在 Linux 下使用 CMake 和 gcc,如果这有什么不同的话。

4

3 回答 3

5

一般定律称为帕累托定律,即 80/20 定律

  • 20%的原因产生80%的后果。

通过分析,您将确定导致应用程序变慢/消耗内存或其他后果的 20% 的最重要原因。如果你解决了 20% 的原因,你将解决 80% 的缓慢/内存消耗等问题......

当然,数字只是数字。只是为了给你它的精神:

  • 您必须只关注真正的主要原因,以便改进优化,直到您满意为止。

从技术上讲,使用 linux 下的 gcc,您所指的问题的答案是“我如何分析在 Linux 中运行的 C++ 代码? ” 简而言之,建议使用:

于 2013-02-25T10:39:58.850 回答
1

正如 Schumi 所说,您可以使用 pstack 之类的东西来获取堆栈样本。但是,您真正需要知道的是为什么程序会花费采样时间。也许您可以仅从一堆函数名称中弄清楚这一点。如果您还可以看到发生调用的代码行,那就更好了。如果您可以看到参数值和数据上下文,那就更好了。原因是,与您正在寻找“热点”、“慢方法”、“瓶颈”的流行概念相反——即基于测量的视角,寻找最有价值的东西是正在完成的可以消除的事情。

换句话说,当您在调试器中停止程序时,将它正在做的任何事情都视为一个错误。试着想办法不做那件事。然而,在你取另一个样本并看到它在做同样的事情之前,不要这样做——不管你如何描述那件事。现在您知道这需要大量时间。多少时间?没关系 - 修复后您会发现。你知道这是很多。在看到它两次之前你必须采取的样本越少,它就越大。

然后是“放大效应”。在你修复了那个“速度错误”之后,程序将花费更少的时间——但是——这不是唯一的。还有其他的,现在他们花费了更多的时间。所以再做一遍。当你完成这个时,如果程序比玩具还大,你可能会惊讶于它的速度有多快。 这是 43 倍的加速。 这是 730 倍的加速。 这是它背后的可怕数学。

你看,工具的问题是你为采样的便利性付出了代价。由于您将其视为度量,因此您不会专注于代码执行其正在执行的操作的原因-可疑的原因。这会导致您错过使代码更快的机会,导致您错过放大效果,导致您在远远没有达到最终可能的加速时停下来。

编辑:为火焰道歉。现在回答你的问题 - 我直到最后才打开编译器优化,因为它可以掩盖更大的问题。然后我尝试做一个打开了优化的构建,但仍然有符号信息,所以调试器可以获得合理的堆栈跟踪并检查变量。当我遇到递减的加速回报时,我可以看到优化器仅通过测量总时间就产生了多大的差异——不需要分析器。

于 2013-02-25T13:42:11.763 回答
1

如果您需要收集堆栈样本,为什么要通过调试器来完成。定期运行 pstack。您可以将每次运行的输出重定向到不同的文件,然后再分析这些文件。通过查看这些文件的调用堆栈,您可能会找出热函数。您不需要调试二进制文件,并且可以在完全优化的二进制文件上执行上述操作。

我更喜欢使用探查器工具来执行上述操作或执行您引用的线程中列出的操作。他们快速查明最热门的函数,您可以通过查看调用者被调用者图来了解调用堆栈。我会花时间了解调用者被调用者堆栈,而不是使用上述方法分析随机堆栈。

于 2013-02-25T10:47:32.397 回答