你最喜欢的 C++ 分析工具是什么?

92

你想要1)测量,还是2)找到加速?如果你想要2),并且认为需要1),那就不是这样的。要找到加速,你不需要“非常精细的结果”。如果程序花费90%的时间在某些你知道可以很好地移除的操作上,stack samples会在10次中有9次向你展示它。如果你查看了10个样本,你是否关心你看到它10次、9次或8次?无论哪种方式,你知道它是什么。测量的百分比并不重要。 - Mike Dunlavey
21个回答

38

针对Linux开发(尽管其中一些工具可能适用于其他平台)。 这是我知道的两个重要工具,还有许多较小的工具已经有一段时间没有进行过活跃的开发。


29

对于Linux系统: Google Perftools

  • 比Valgrind更快(但细粒度较差)
  • 不需要代码仪器化
  • 有良好的图形化输出(--> kcachegrind)
  • 可以进行内存分析、CPU性能分析和泄漏检测

10

在我看来,使用调试器进行取样sampling using a debugger是最好的方法。你只需要一个IDE或调试器就可以让程序停下来。这样可以在安装分析器之前解决性能问题。


3
是的!这对我非常有效。它不需要仪器设备,也不需要安装任何分析工具。在Linux系统上,您可以使用gdb来运行程序,速度很快。按下Ctrl+C停止,键入'bt'以显示堆栈跟踪,然后按'c'继续,再次按下Ctrl+C即可。非常好用!使用此技术,在复杂的程序中将执行时间缩短了20%。太棒了! - Hugh Perkins
@HughPerkins:感谢您的编辑,我很高兴您取得了成功。(我敢打赌您可以做得比20%更好 :)) - Mike Dunlavey
1
是的,我仅使用gdb + ctrl-c,在几个小时的工作中,将迭代时间从1200毫秒降至200毫秒,以定位热点 :-) - Hugh Perkins
@HughPerkins:对我来说,如果我在处理自己的代码时,很难知道何时停止尝试——似乎我总是可以再挤出一些。当我在处理别人的代码时,可能会遇到问题。我不能总是说服代码的“所有者”去解决问题,因此进程就会停滞不前。这是一个有趣的难题。 - Mike Dunlavey
如果您只想在Linux上实现此操作而不需要仪器,甚至不需要调试器或IDE。只需运行“pstack <pid>”以跟踪当前正在运行的指令的堆栈跟踪。这比启动调试器、手动中断然后查找堆栈跟踪要简单得多。 - Manish Sogi
@ManishSogi:你说得对。可惜我已经很久没有使用Linux了。实际上,我喜欢查看的不仅仅是堆栈跟踪,还包括变量以及从当前例程中退出,这样我可以更好地了解它正在做什么以及为什么要这样做。 - Mike Dunlavey

7

我唯一使用过的C++代码分析工具是由AutomatedQA(现在是SmartBear Software)开发的AQTime。它内置了几种类型的分析器(性能、内存、Windows句柄、异常跟踪、静态分析等),并对代码进行插桩以获取结果。

我很喜欢使用它——总是很有趣地找到那些代码微小更改可以显著提高性能的地方。


很遗憾,那只在Windows上有效。 - Bram

6

我以前从未进行过性能剖析。昨天我编写了一个ProfilingTimer类,其中包括静态时间表(a map<std::string, long long>)来存储时间。

构造函数存储起始时间戳,析构函数计算经过的时间并将其添加到地图中:

ProfilingTimer::ProfilingTimer(std::string name)
 : mLocalName(name)
{
 sNestedName += mLocalName;
 sNestedName += " > ";

 if(sTimetable.find(sNestedName) == sTimetable.end())
  sTimetable[sNestedName] = 0;

 mStartTick = Platform::GetTimerTicks();
}

ProfilingTimer::~ProfilingTimer()
{
 long long totalTicks = Platform::GetTimerTicks() - mStartTick;

 sTimetable[sNestedName] += totalTicks;

 sNestedName.erase(sNestedName.length() - mLocalName.length() - 3);
}

在我想要分析的每个函数(或{块})中,我需要添加以下内容:
ProfilingTimer _ProfilingTimer("identifier");

这行代码在我想要分析的所有函数中添加起来有点麻烦,因为我必须猜测哪些函数需要很长时间。但它的效果很好,print函数会显示耗费时间的百分比。

(还有其他人使用类似的“自制分析”吗?或者这只是愚蠢的?但这很有趣!你们有什么改进建议吗?

是否有一种自动向所有函数添加一行代码的方法?)


5

Visual Studio 2008 中的分析器非常好用:快速、用户友好、清晰,并且与 IDE 集成良好。


2
调试工具不是只有团队版才有吗? - dwj
@dwj:我不确定。我正在使用Visual Studio Team System 2008 Development Edition。 - Dimitri C.
看起来在2010年之前的版本中,这只适用于Team版(https://dev59.com/FbegzYgBFxS5KdRjwIf9#61681)。 - dwj

5
我过去经常使用Glowcode,并且一直以来都有很好的体验。它与Visual Studio的集成非常方便,并且是我使用过的最高效/直观的分析器(即使与托管代码的分析器相比也是如此)。
显然,如果您不在Windows上运行,那就没用了,但是这个问题让我不清楚您具体的需求是什么。

5

毫无疑问,oprofile是最简单可靠的工具之一,它能够完成任务并提供各种漂亮的数据细分。


4
对于Windows系统,可以使用Xperf进行检查。它使用采样分析,具有一些有用的用户界面,且不需要插装。非常适合跟踪性能问题。你可以回答以下问题:
  • 谁在使用最多的CPU?使用调用堆栈深入到函数名。
  • 谁在分配最多的内存?
  • 谁在执行最多的注册表查询?
  • 磁盘写入?等等。
当你找到瓶颈时,你会感到惊讶,因为它们可能不在你预期的地方!

4

由于您没有提到您所使用的平台,我会建议在Linux下使用cachegrind。这是Valgrind工具集的一部分。

http://valgrind.org/info/tools.html

我从未使用过它的子功能Callgrind,因为我大多数的代码优化都是针对内部函数的。

请注意,有一个名为KCachegrind的前端可用。


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