在积极内联的情况下分析C ++?

时间:2010-01-18 17:23:01

标签: c++ profiling

我试图找出我的C ++程序花费时间的地方,使用gprof。这是我的困境:如果我使用我用于发布版本的相同优化设置进行编译,几乎所有内容都被内联,并且gprof告诉我,无益的是,我90%的时间花在核心例程中,其中所有内容都是内联的。另一方面,如果我使用内联禁用编译,则程序运行速度会慢一个数量级。

我想知道当我的程序编译时启用内联时,从我的核心例程调用的程序花了多少时间。

我在四核Intel机器上运行64位Ubuntu 9.04。我查看了google-perftools,但这似乎不适用于x86_64。在32位计算机上运行不是一种选择。

当启用内联时,是否有人建议如何更有效地配置我的应用程序?

编辑:以下是我的问题的一些说明。如果最初不清楚我会道歉。

我想知道在我的应用程序中花费的时间。分析我的优化构建导致gprof告诉我,大约90%的时间花在main上,其中所有内容都是内联的。在分析之前我已经知道了!

我想知道的是内联函数花了多少时间,最好不要在我的构建选项中禁用优化或内联。在使用内联禁用进行性能分析时,应用程序的速度会慢一个数量级。这种执行时间的差异是一个方便的问题,但是,我不确定使用内联禁用构建的程序的性能配置文件是否与使用内联启用的程序的性能配置文件强烈对应。

简而言之:有没有办法在没有禁用优化或内联的情况下获取有用的分析信息

6 个答案:

答案 0 :(得分:9)

我认为你想要做的是找出哪些代码行花费了你足够的价值来优化。这与计时功能非常不同。 You can do better than gprof.

Here's a fairly complete explanation of how to do it.

您可以手动执行此操作,也可以使用其中一个可提供相同信息的配置文件,例如oprofileRotateRight/Zoom

BTW,只有当内联的例程很小并且不调用函数本身时,并且如果它们被调用的行足够活跃,那么内联才具有重要意义。

至于调试和发布版本之间的数量级性能比,可能是由于许多事情,可能是也可能不是内联。您可以使用上面提到的stackshot方法来确定在任何一种情况下发生了什么。我发现调试版本可能因其他原因而变慢,例如递归数据结构验证。

答案 1 :(得分:2)

使用CPU的高性能计时机制(例如x86)开发一些宏 - 不依赖于系统调用的例程,并将运行核心循环的单个线程绑定到特定的CPU(set the affinity)。您需要实现以下宏。

PROF_INIT //allocate any variables -- probably a const char
PROF_START("name") // start a timer
PROF_STOP() // end a timer and calculate the difference -- 
            // which you write out using a async fd

我有这样的东西,我放在我感兴趣的每个函数中,我确保宏将定时调用放入调用树的上下文中 - 这可能是最准确的分析方式。

注意:

此方法由您的代码驱动 - 并且不依赖于外部工具以任何方式 snoop 您的代码。当涉及到小部分代码时,窥探,采样和中断驱动的分析是不准确的。此外,您希望控制收集时序数据的位置和时间 - 例如代码中的特定构造,如循环,递归调用链的开始或大容量存储器分配。

- 编辑 -

您可能对link from this answer to one of my questions感兴趣。

答案 2 :(得分:2)

您可以使用更强大的分析器,例如英特尔的VTune,它可以为您提供流水线级别的性能细节。

http://software.intel.com/en-us/intel-vtune/

适用于Windows和Linux,但确实需要花钱......

答案 3 :(得分:2)

valgrind会更有帮助吗?

结合KCachegrind GUI,它提供了一种免费且简单的方法来浏览适用于内联代码的注释代码。 在这里你有一个非常简单的指示:http://web.stanford.edu/class/cs107/guide_callgrind.html

答案 4 :(得分:0)

代码运行速度慢(当然除了你的方便)并不重要 - 分析器仍会告诉你在每个函数中花费的正确时间比例。

答案 5 :(得分:0)

您可以使用gcov为您提供逐行执行计数。这至少应该告诉你哪些内联函数是瓶颈。