超越堆栈采样:C ++ Profilers

时间:2010-12-09 03:36:44

标签: c++ qt optimization profiling profiler

19 个答案:

答案 0 :(得分:60)

首先:

时间采样分析器比CPU采样分析器更强大。我对Windows开发工具并不是很熟悉,所以我不知道哪些是哪种。大多数分析器都是CPU采样。

CPU采样分析器每N条指令抓取一次堆栈跟踪 此技术将揭示代码中受CPU限制的部分代码。如果这是您应用程序中的瓶颈,那就太棒了。如果您的应用程序线程花费大部分时间来争用互斥锁,那就不那么好了。

时间采样分析器每N微秒抓取一次堆栈跟踪 这项技术将归零“慢”代码。原因是否是CPU绑定,阻止IO绑定,互斥绑定或缓存颠簸部分代码。简而言之,任何一段代码都会减慢你的应用程序的速度。

所以尽可能使用时间采样分析器,特别是在分析线程代码时。

第二

采样分析器生成大量数据。这些数据非常有用,但通常有太多不易使用的数据。配置文件数据可视化器在这里有很大帮助。我找到的用于配置文件数据可视化的最佳工具是gprof2dot。不要让这个名字欺骗你,它会处理各种采样分析器输出(AQtime,Sleepy,XPerf等)。一旦可视化指出了违规函数,就跳回到原始配置文件数据,以便更好地了解真正的原因。

gprof2dot工具会生成dot graph description,然后您可以将其输入graphviz工具。输出基本上是一个调用图,其功能颜色由它们对应用程序的影响进行编码。 alt text

一些提示让gprof2dot生成好的输出。

  • 我在图表上使用了--skew 0.001,因此我可以轻松查看热门代码路径。否则int main()支配图表。
  • 如果你在使用C ++模板做任何疯狂的事情,你可能想要添加--strip。对于Boost来说尤其如此。
  • 我使用OProfile生成我的采样数据。为了获得良好的输出,我需要将其配置为从我的第三方和系统库加载调试符号。一定要做同样的事情,否则你会发现CRT占你应用程序时间的20%是真正发生的事情malloc正在摧毁堆积并且吃掉了15%。

答案 1 :(得分:15)

当您尝试随机暂停时发生了什么?我一直在怪物应用程序上使用它。你说它没有提供足够的信息,你建议你需要高分辨率。有时人们需要一些帮助才能理解如何使用它。

在VS下,我所做的是配置堆栈显示,因此它不会向我显示函数参数,因为这会使堆栈显示完全不可读,IMO。

然后,在我等待的过程中,通过点击“暂停”来拍摄大约10个样本。我使用^ A,^ C和^ V将它们复制到记事本中,以供参考。然后我研究每一个,试图找出当时试图完成的过程。

如果它试图在2个或更多样本上完成某些事情,并且那个事情并非绝对必要,那么我发现了一个实时问题,而且我大致知道它会节省多少修复。

有些事情你真的不需要知道,比如精确百分比并不重要,第三方代码中的内容并不重要,因为你无法对那些。您可以做的是在可以修改的代码中丰富的一组调用点,显示在每个堆栈样本上。那是你快乐的狩猎场。

我找到的各种事物的例子:

  • 在启动过程中,在尝试从DLL资源中提取国际化字符串的过程中,它可能大约有30层。如果检查实际的字符串,很容易就会发现字符串实际上不需要需要进行国际化,就像它们是用户从未真正看到过的字符串一样。

  • 在正常使用期间,某些代码无意中在某个对象中设置了Modified属性。该对象来自一个超类,它捕获变化并触发通知,这些通知在整个数据结构中波动,操纵UI,以难以预见的方式创建和消除对象。这可能会发生很多 - 通知的意外后果。

  • 逐行填写工作表,逐个单元格。事实证明,如果你从一组数值中一次性构建行,它会快得多。

P.S。如果你是多线程的,当你暂停它时,所有线程都会暂停。看一下每个线程的调用堆栈。机会是,其中只有一个是真正的罪魁祸首,其他人都是空转。

答案 2 :(得分:8)

我在AMD CodeAnalyst取得了一些成功。

答案 3 :(得分:7)

你有MFC OnIdle功能吗?在过去,我有一个近乎实时的应用程序,我必须修复,当设置为19.2K的速度,PentiumD应该能够跟上时,丢弃串行数据包。 OnIdle功能就是杀人的东西。我不确定QT是否有这个概念,但我也会检查它。

答案 4 :(得分:4)

重新启用VS Profiler - 如果它生成了如此大的文件,那么您的采样间隔可能过于频繁?尝试降低它,因为你可能还有足够的样本。

理想情况下,确保在实际操作问题区域之前不收集样本。所以从收集暂停开始,让你的程序进行“慢活动”,然后开始收集。您最多只需要20秒的收集时间。在此之后停止收集。

这有助于减少样本文件大小,并且只捕获分析所需的内容。

答案 5 :(得分:4)

我已成功将PurifyPlus用于Windows。虽然它不便宜,但IBM提供的试用版略有瘫痪。使用量化进行性能分析所需的只是pdb文件,并与/ FIXED链接:NO。唯一的缺点:不支持Win7 / 64。

答案 6 :(得分:3)

另外两个工具建议。

Luke Stackwalker有一个可爱的名字(即使它的尝试有点困难),它不会花费你任何东西,你得到源代码。它声称也支持多线程程序。所以它肯定值得一试。

http://lukestackwalker.sourceforge.net/

Glowcode,我已经向我指出值得使用:

http://www.glowcode.com/

不幸的是我暂时没有做任何PC工作,所以我没有尝试过其中任何一种。我希望这些建议无论如何都有帮助。

答案 7 :(得分:3)

如果您对事件循环有疑问,可以覆盖QCoreApplication::notify()和dosome手动分析(发送者/事件的一个或两个映射到计数/时间)吗?

我认为你首先记录事件类型的频率,然后更仔细地检查这些事件(哪个对象发送它,它包含什么,等等)。跨线程的信号是隐式排队的,因此它们最终会出现在事件循环中(显然也是显式的排队连接)。

我们已经完成了在事件处理程序中捕获和报告异常,所以每个事件都会在那里进行。

只是一个想法。

答案 8 :(得分:3)

结帐XPerf

这是MS提供的免费,非侵入性和可扩展的分析器。它是由Microsoft开发的,用于配置Windows。

答案 9 :(得分:3)

Easyprofiler - 我还没有看到它在这里提到,所以不确定你是否已经看过它了。它在收集度量标准数据方面采用了略微不同的方法。使用其编译时配置文件方法的一个缺点是您必须对代码库进行更改。因此,您需要了解缓慢的位置,并在那里插入分析代码。

根据你的最新评论,听起来你至少在做出一些的进展。也许这个工具可能会为您提供一些有用的指标。如果没有别的东西它有一些真正的图表和图片:P

答案 10 :(得分:2)

编辑:我现在看到你在第一篇文章中提到了这一点。该死的,我从未想过我会成为那个人。

您可以使用Pin来更精细地检测代码。我认为Pin会让你创建一个工具来计算你输入函数的次数或你在那里花了多少时钟,大致模仿像VTune或CodeAnalyst这样的东西。然后,您可以删除哪些功能进行检测,直到您的计时问题消失为止。

答案 11 :(得分:2)

我可以告诉你我每天使用的东西。

a)AMD代码分析师

  • 这很容易,它会让您快速了解正在发生的事情。大部分时间都可以。
  • 使用AMD CPU,它会告诉你有关cpu管道的信息,但只有在你有大量循环时才需要它,如图形引擎,视频编解码器等。

b)VTune。

  • 它在vs2008

  • 中得到了很好的整合
  • 在您了解热点之后,您不仅需要对时间进行采样,还需要对缓存未命中和内存使用等其他内容进行采样。这非常重要。设置采样会话,然后编辑属性。我总是抽样测试时间,内存读/写和缓存未命中(三次不同的运行)

但是,除了工具之外,您还需要获得分析经验。这意味着要了解CPU /内存/ PCI的工作原理......所以,这是我的第三个选择

c)单元测试

如果您正在开发需要巨大性能的大型应用程序,这一点非常重要。如果您无法在某些部分拆分应用程序,则很难跟踪CPU使用情况。我没有测试所有的案例和类,但我有硬编码的执行和具有重要功能的输入文件。

我的建议是在几个小测试中使用随机抽样,并尝试标准化配置文件策略。

答案 12 :(得分:1)

我刚刚完成了CxxProf的第一个可用版本,这是一个用于C ++的便携式手动检测分析库。

它实现了以下目标:

  • 易于集成
  • 在编译期间轻松删除lib
  • 在运行时轻松删除lib
  • 支持多线程应用程序
  • 支持分布式系统
  • 保持对最低限度的影响

这些点是从project wiki中删除的,请查看更多详情。

免责声明:我是CxxProf的主要开发者

答案 13 :(得分:1)

我使用xperf / ETW来满足我的所有分析需求。它有一个陡峭的学习曲线,但非常强大。如果您在Windows上进行性能分析,那么您必须知道xperf。我经常使用此分析器在我的代码和其他人的代码中查找性能问题。

在我使用它的配置中:

  • xperf从每个执行代码的核心抓取CPU样本 女士。采样率可以增加到8 KHz和样本 包括用户模式和内核代码。这允许找出什么 线程正在运行
  • xperf记录每个上下文 切换(允许完美重建每个多少时间 线程使用),加上线程切换时的调用堆栈 调用堆栈为什么线程准备另一个线程,允许跟踪 等待链并找出线程未运行的原因
  • xperf 记录所有进程的所有文件I / O
  • xperf记录所有磁盘I / O. 来自所有流程
  • xperf记录哪个窗口处于活动状态,即CPU 频率,CPU电源状态,UI延迟等。
  • xperf也可以记录所有 来自一个进程的堆分配,来自所有进程的所有虚拟分配 流程等等。

对于所有流程来说,这是一个时间轴上的大量数据。 Windows上没有其他的分析器可以做到这一点。

我已经在博客上广泛介绍了如何使用xperf / ETW。这些博客文章和一些专业质量培训视频可在此处找到: http://randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/

如果您想了解如果不使用xperf会发生什么,请阅读以下博文: http://randomascii.wordpress.com/category/investigative-reporting/ 这些是我在其他人的代码中发现的性能问题的故事,应该由开发人员找到。这包括加载到VC ++编译器中的mshtml.dll,VC ++的find-in-files中的拒绝服务,在数量惊人的客户机器中的热量限制,在Visual Studio中缓慢单步执行,在硬件中分配4 GB磁盘驱动程序,powerpoint性能错误等等。

答案 14 :(得分:1)

只是抛弃它,即使它不是一个完整的分析器:如果你所追求的只是挂起事件循环,需要长时间处理一个事件,ad-hoc tool在Qt中是一件简单的事情。这种方法可以很容易地扩展,以跟踪每个事件处理的时间,以及这些事件是什么,等等。它不是一个通用的分析器,而是一个以事件循环为中心的分析器。

在Qt中,所有跨线程信号槽调用都通过事件循环传递,定时器,网络和串行端口通知以及所有用户交互也是如此。因此,观察事件循环是了解应用程序花费时间的重要一步。

答案 15 :(得分:0)

DevPartner最初由NuMega开发,现在由MicroFocus发布,曾经是分析和代码分析(例如内存和资源泄漏)的首选解决方案。 我最近没有尝试过,所以我不能向你保证它会对你有所帮助;但我曾经用它做过很好的结果,所以这是我考虑在我们的代码质量过程中重新安装的替代方案(它们提供了14天的试用期)

答案 16 :(得分:0)

虽然你的操作系统是win7,程序无法在xp下运行? 如何在xp下对其进行分析,结果应该是win7的提示。

答案 17 :(得分:0)

这里列出了大量的个人资料,我自己也尝过其中一些 - 不过我最终写的是基于此:

http://code.google.com/p/high-performance-cplusplus-profiler/

当然要求你修改代码库,但它非常适合缩小瓶颈,应该适用于所有x86(可能是多核盒子的问题,即它使用rdtsc,但是 - 这纯粹是为了无论如何都是指示性的时间 - 所以我发现它足以满足我的需求..)

答案 18 :(得分:0)

我使用Orbit profiler,简单,开源且功能强大! https://orbitprofiler.com/