带循环检测的 Callgrind 性能分析

ara*_*ser 5 c++ profiling callgrind kcachegrind

我第一次尝试使用 Callgrind/Kcachegrind 来分析我的 C++ 应用程序,我注意到需要更多时间的两个函数是:

  1. <周期1>(50%自我)和
  2. do_lookup_x(15% 自我)

现在,根据我的理解,周期 1 与递归调用函数所花费的时间的估计有关,但我不太清楚应该如何解释这里花费的如此长的时间。如果有一些周期,我想看看哪个函数被调用得更频繁并且最终占用了更多的CPU时间。如果我禁用循环检测(查看 -> 循环检测),则循环 1 会消失,但“自我”时间总计约为 60%,我不确定这是否是最好的做法。关于 do_lookup_x 我完全一无所知......

您能澄清一下我应该如何解释这些结果吗?

提前致谢。

osg*_*sgx 4

KCachegrind 中可能会错误地检测到循环: http://valgrind.org/docs/manual/cl-manual.html#cl-manual.cycles

6.2.4. 避免循环 通俗地说,循环是一组以递归方式相互调用的函数。...

循环本身并不坏,但往往会使代码的性能分析变得更加困难。这是因为一个周期内的调用的包含成本是没有意义的。包含成本的定义,即函数的自身成本加上其被调用者的包含成本,需要函数之间的拓扑顺序。对于循环,这并不成立:循环中函数的被调用者包括函数本身。因此,KCachegrind 会进行循环检测并跳过循环内调用的任何包含成本的可视化。此外,一个循环中的所有函数都被折叠成称为循环 1 的人工函数。

现在,当程序暴露出非常大的循环时(对于某些 GUI 代码,或者在使用基于事件或回调的编程风格的一般代码中,情况就是如此),您将失去良好的属性,让您可以通过跟踪来自 main、guided 的调用链来查明瓶颈。通过包含成本。此外,KCachegrind 失去了显示调用图的有趣部分的能力,因为它使用包含成本来切断不感兴趣的区域。

尽管周期中包含的成本毫无意义,但可视化的一大缺点激发了在 KCachegrind 中暂时关闭周期检测的可能性,这可能会导致误导性的可视化。然而,由于独立调用链的不幸叠加,分析结果会出现循环,因此经常会出现循环。忽视具有非常小的测量包容性成本的无趣调用将会打破这些循环。在这种情况下,通过不检测循环来错误处理循环仍然会提供有意义的分析可视化。

尝试在 KCachegrind 的“视图”菜单中关闭“周期检测”并检查“Self”时间列,因为“Incl”将不正确。

您还可以尝试其他一些具有精确且完整功能堆栈保存的分析器。https://github.com/jrfonseca/gprof2dot脚本支持的许多分析器都会保存完整堆栈,而不仅仅是 callgrind/cachegrind 格式中的被调用者-调用者对。