我正在尝试寻找开源剖析器,而不是使用需要支付$$$的商业剖析器。当我在SourceForge上进行搜索时,我发现了这四个C++剖析器,它们似乎很有前途:
- Shiny: C++剖析器
- 低消耗剖析器
- Luke Stackwalker
- FreeProfiler
我不确定哪一个剖析器在学习程序性能方面最好使用,希望能听到一些建议。
有不止一种方法可以完成它。
大多数剖析器假设您需要1)高时间统计精度(大量样本),以及2)低问题识别精度(函数和调用图)。
这些优先级可以反转。也就是说,可以将问题定位到精确的机器地址,而成本精度则取决于样本数量。
大多数真正的问题至少会花费10%,其中高精度并不是必需的。
例如:如果某些代码使您的程序运行时间比应该长两倍,则表示其中某些代码的成本为50%。如果您在其运行缓慢时对调用堆栈进行了10次采样,则精确的代码行将出现在其中约5个样本中。程序越大,问题发生在堆栈中间某个函数调用的可能性就越大。
这很反直觉,我知道。
注意:xPerf已经接近目标,但还差一点(据我所知)。它采样调用堆栈并保存它们-这很好。以下是我认为它需要的:
只有在您想要它们时,它才应该采样。因为现在您必须过滤掉不相关的内容。
在堆栈视图中,它应该显示特定行或地址,在这些位置进行调用,而不仅仅是整个函数。(也许它可以做到这一点,我无法从博客中得知。)
如果单击以获取蝴蝶图,以单个调用指令或叶指令为中心,则它应该向您显示包含该指令的堆栈样本的分数,而不是CPU分数。那将是该指令成本的直接度量,作为时间的一个分数。(也许它可以做到这一点,我无法得知。) 例如,即使指令是对文件打开或其他使线程处于空闲状态的调用,它仍然会花费墙钟时间,您需要知道这一点。
注意:我刚刚仔细查看了Luke Stackwalker,同样的评论适用。我认为它正在正确的轨道上,但需要UI工作。
添加:仔细查看了LukeStackwalker后,恐怕它成为衡量函数比定位语句更重要的假设的受害者。因此,在每个调用堆栈的样本上,它更新函数级别的时间信息,但是所有行号信息都只是在每个函数中跟踪最小和最大行号,这些行号随着它采取的样本越来越远。因此,它基本上丢弃了最重要的信息-行号信息。这很重要的原因是,如果您决定优化一个函数,则需要知道其中哪些行需要修改,并且这些行在堆栈样本中(在它们被丢弃之前)。
有人可能会反对,认为如果保留行号信息,存储空间会很快用完。但有两个答案。1)样本中只显示有限的行数,并且这些行数会重复出现。2)不需要太多的样本 - 高统计精度的测量是必要的假设,但从未得到证明。在这些列出的工具中,我发现Luke Stackwalker是最好用的——我喜欢它的图形用户界面,而且很容易上手。
另一个类似的工具是Very Sleepy——功能类似,采样似乎更可靠,但图形用户界面可能稍微难用一些(不太图形化)。
经过更多时间的使用,我发现其中一个相当重要的缺陷。虽然两者都尝试以1毫秒的分辨率进行采样,但实际上它们无法实现,因为它们的采样方法(附加进程的StackWalk64)太慢了。对于我的应用程序,获取调用堆栈需要花费大约5-20毫秒的时间。这不仅使结果不精确,而且也会使结果偏斜,因为短的调用堆栈走得更快,因此往往会获得更多的命中次数。
虽然不是开源的,但AMD CodeAnalyst是免费的。尽管名字中有“AMD”,但它也适用于Intel CPU。可在Windows(与Visual Studio集成)和Linux上使用。