【问题标题】:gprof vs cachegrind profilesgprof 与 cachegrind 配置文件
【发布时间】:2011-09-13 02:06:03
【问题描述】:

在尝试优化代码时,我对kcachegrdindgprof 生成的配置文件的差异感到有些困惑。具体来说,如果我使用 gprof(使用 -pg 开关等编译),我有这个:

Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 89.62      3.71     3.71   204626     0.02     0.02  objR<true>::R_impl(std::vector<coords_t, std::allocator<coords_t> > const&, std::vector<unsigned long, std::allocator<unsigned long> > const&) const
  5.56      3.94     0.23 18018180     0.00     0.00  W2(coords_t const&, coords_t const&)
  3.87      4.10     0.16   200202     0.00     0.00  build_matrix(std::vector<coords_t, std::allocator<coords_t> > const&)
  0.24      4.11     0.01   400406     0.00     0.00  std::vector<double, std::allocator<double> >::vector(std::vector<double, std::allocator<double> > const&)
  0.24      4.12     0.01   100000     0.00     0.00  Wrat(std::vector<coords_t, std::allocator<coords_t> > const&, std::vector<coords_t, std::allocator<coords_t> > const&)
  0.24      4.13     0.01        9     1.11     1.11  std::vector<short, std::allocator<short> >* std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<std::vector<short, std::alloca

这似乎表明除了::R_impl(...)之外我不需要费心寻找任何地方

同时,如果我在不使用-pg 开关的情况下编译并改为运行valgrind --tool=callgrind ./a.out,我有一些相当不同的东西:这是kcachegrind 输出的屏幕截图

如果我解释正确,这似乎表明::R_impl(...) 只需要大约 50% 的时间,而另一半则用于线性代数(Wrat(...)eigenvalues 和底层的 lapack 调用)在gprof 配置文件的下方。

我知道gprofcachegrind 使用不同的技术,如果他们的结果有些不同,我不会打扰。但是在这里,它看起来非常不同,我不知道如何解释这些。有什么想法或建议吗?

【问题讨论】:

    标签: c++ optimization profiling valgrind gprof


    【解决方案1】:

    您正在查看错误的列。您必须查看 kcachegrind 输出中的第二列,即名为“self”的列。这是特定子例程仅在不考虑其子例程的情况下花费的时间。第一列是累积时间(它等于主要机器时间的 100%),但信息量不大(在我看来)。

    请注意,从 kcachegrind 的输出中,您可以看到进程的总时间为 53.64 秒,而在子例程“R_impl”中花费的时间为 46.72 秒,占总时间的 87%。所以 gprof 和 kcachegrind 几乎完全一致。

    【讨论】:

    • 我认为默认情况下 callgrind 在机器指令中显示函数成本。在屏幕截图中,我们实际上看到了以百分比表示的相对成本。因此,R_impl 包含 46.72% 的分析期间执行的所有指令。
    【解决方案2】:

    gprof 是一个instrumented 分析器,callgrind 是一个采样 分析器。使用插桩分析器,您会为每个函数的进入和退出增加开销,这可能会导致配置文件出现偏差,尤其是当您有相对较小的函数被多次调用时。采样分析器往往更准确 - 它们会稍微减慢整个程序的执行速度,但这往往会对所有函数产生相同的相对影响。

    试试Zoom from RotateRight 的 30 天免费评估 - 我怀疑它会给你一个更符合 callgrind 而不是 gprof 的个人资料。

    【讨论】:

    • 所以你的意思是——扔掉 gprof 的输出,这是公然错误的,对吗?
    • gprof 对于一些类型的分析很有用——它产生比采样分析器更准确的调用图信息,它还可以为某些类型的代码(例如,主要是大型函数时)。尝试使用其他分析器(例如 Zoom)就实时配置文件的外观获得“决定性投票”。
    • @Zhenya:保罗说得对。尝试缩放。 gprofproblems。 BTW gprof 是一个采样器,但仅适用于 PC,并且仅在 CPU 受限期间,因此它对系统调用所花费的时间视而不见。它插入函数入口代码不是为了测量函数时间,而是将 PC 命中归功于更高级别的调用者。然后它会做出各种各样的假设来弄乱结果。它确实为您提供了图形信息,但除非您的程序很小(并且没有递归),否则并不能说明太多。
    • @Mike,@Paul:谢谢!出于好奇:在 Zoom 和英特尔的 VTune 之间进行选择有什么具体的优点和/或缺点吗?
    • 什么? gprof 正在采样(它将每 10 或 1 ms 对 PC 进行采样以获得输出中的 %% 计数)并且 cachegrind/callgrind 正在检测(他们使用 valgrind 动态检测代码并通过检测统计进行计数 - 在基本块层)。 Cachegrind/callgrind 甚至可以模拟分析器,因为测量的不是实时,而是虚拟事件(模拟缓存层次结构、模拟分支预测、无任何停顿的指令获取)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多