推荐的开源分析工具

14

我正在尝试寻找开源剖析器,而不是使用需要支付$$$的商业剖析器。当我在SourceForge上进行搜索时,我发现了这四个C++剖析器,它们似乎很有前途:

  1. Shiny: C++剖析器
  2. 低消耗剖析器
  3. Luke Stackwalker
  4. FreeProfiler

我不确定哪一个剖析器在学习程序性能方面最好使用,希望能听到一些建议。


什么平台?我在Linux上使用g++时会使用gprof。 - David Thornley
我的程序在Windows XP上运行。 - stanigator
6个回答

6
你可以尝试使用“Windows性能工具包”,它完全免费。这篇博客文章提供了如何进行基于采样的分析的示例。链接为:Windows Performance Toolkit博客文章

我刚刚查看了一下,但是我发现我需要在我的电脑上运行Windows Vista或Server 2008才能安装它。由于我不想在我的开发笔记本电脑上安装Windows Vista(它是运行XP的),所以我认为我不能亲自选择这个选项。无论如何,感谢你的建议。 - stanigator
我更喜欢Very Sleepy或者Luke Stackwolker。xPerf在理论上听起来不错,但实际使用起来非常棘手 - 很难启动,处理数据速度缓慢。 - Suma

5

3

有不止一种方法可以完成它。

不要忘记无剖析器的方法。

大多数剖析器假设您需要1)高时间统计精度(大量样本),以及2)低问题识别精度(函数和调用图)。

这些优先级可以反转。也就是说,可以将问题定位到精确的机器地址,而成本精度则取决于样本数量。

大多数真正的问题至少会花费10%,其中高精度并不是必需的。

例如:如果某些代码使您的程序运行时间比应该长两倍,则表示其中某些代码的成本为50%。如果您在其运行缓慢时对调用堆栈进行了10次采样,则精确的代码行将出现在其中约5个样本中。程序越大,问题发生在堆栈中间某个函数调用的可能性就越大。

这很反直觉,我知道。

注意:xPerf已经接近目标,但还差一点(据我所知)。它采样调用堆栈并保存它们-这很好。以下是我认为它需要的:

  • 只有在您想要它们时,它才应该采样。因为现在您必须过滤掉不相关的内容。

  • 在堆栈视图中,它应该显示特定行或地址,在这些位置进行调用,而不仅仅是整个函数。(也许它可以做到这一点,我无法从博客中得知。)

  • 如果单击以获取蝴蝶图,以单个调用指令或叶指令为中心,则它应该向您显示包含该指令的堆栈样本的分数,而不是CPU分数。那将是该指令成本的直接度量,作为时间的一个分数。(也许它可以做到这一点,我无法得知。) 例如,即使指令是对文件打开或其他使线程处于空闲状态的调用,它仍然会花费墙钟时间,您需要知道这一点。

注意:我刚刚仔细查看了Luke Stackwalker,同样的评论适用。我认为它正在正确的轨道上,但需要UI工作。

添加:仔细查看了LukeStackwalker后,恐怕它成为衡量函数比定位语句更重要的假设的受害者。因此,在每个调用堆栈的样本上,它更新函数级别的时间信息,但是所有行号信息都只是在每个函数中跟踪最小和最大行号,这些行号随着它采取的样本越来越远。因此,它基本上丢弃了最重要的信息-行号信息。这很重要的原因是,如果您决定优化一个函数,则需要知道其中哪些行需要修改,并且这些行在堆栈样本中(在它们被丢弃之前)。

有人可能会反对,认为如果保留行号信息,存储空间会很快用完。但有两个答案。1)样本中只显示有限的行数,并且这些行数会重复出现。2)不需要太多的样本 - 高统计精度的测量是必要的假设,但从未得到证明。
我怀疑其他堆栈采样器,如xPerf,也存在类似的问题。

2

在这些列出的工具中,我发现Luke Stackwalker是最好用的——我喜欢它的图形用户界面,而且很容易上手。

另一个类似的工具是Very Sleepy——功能类似,采样似乎更可靠,但图形用户界面可能稍微难用一些(不太图形化)。


经过更多时间的使用,我发现其中一个相当重要的缺陷。虽然两者都尝试以1毫秒的分辨率进行采样,但实际上它们无法实现,因为它们的采样方法(附加进程的StackWalk64)太慢了。对于我的应用程序,获取调用堆栈需要花费大约5-20毫秒的时间。这不仅使结果不精确,而且也会使结果偏斜,因为短的调用堆栈走得更快,因此往往会获得更多的命中次数。


你好,Suma。在我看来,了解每行代码(或函数,如果你愿意)所用总时间的近似百分比比精确的绝对时间更重要,并且时间百分比不应受采样开销或采样频率的影响。 - Mike Dunlavey
我们之前在类似的讨论中已经见过面,所以我会重复一下。你对我正在分析的工作负载类型的假设是错误的。我最感兴趣的是最慢帧的性能。这些帧并不占据10%,而是少得多。导致问题的个别函数通常只占总应用运行时间的1%或更少。慢帧的持续时间通常为50-100毫秒。将它们以20个样本采样是完全不能接受的。 - Suma
不想让你感到疲劳。所以偶尔会出现一个需要花费太长时间的框架。顺便说一下,我会通过一个外部循环将每个框架放大100倍(基本上是将我的认知速度提高100倍),当一个框架花费太长时间时,就会强制停止它。虽然有些笨拙,但这就是我会做的事情。不需要回复。 - Mike Dunlavey
1
好的,如果你不能在改变语义的情况下放大帧的执行,那么问题就更难了。那么,我会尝试使用类似闹钟的中断。如果一个快速帧需要10毫秒,而慢一些的帧需要50毫秒,在帧的开始处设置一个(20+-随机)毫秒的闹钟,在帧的结束时清除闹钟。这样,闹钟只在慢帧中响起,然后你就可以获取样本。计时器设置和抓取并不需要很快,因为它不会影响帧代码的执行。我有点儿迟钝,但这样做有什么问题吗? - Mike Dunlavey
我之所以一再强调性能的重要性,是因为人们对此有一些愚蠢的想法。这只是告诉你需要知道的内容,即当代码执行时间过长时,基于百分比的语义分析是必要的。为了进行这种分析,可能需要使用一些技巧,例如放大或人为减慢执行速度。这些不会显著改变百分比。这是一种不同的思考方式,在SO上有很多评论报告了实质性的结果。我相信你已经理解了这一点。 - Mike Dunlavey
显示剩余11条评论

2

虽然不是开源的,但AMD CodeAnalyst是免费的。尽管名字中有“AMD”,但它也适用于Intel CPU。可在Windows(与Visual Studio集成)和Linux上使用。


0

我们使用LtProf,并对其感到满意。虽然不是开源的,但只需要$$,而不是$$$ :-)


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