C ++分析(谷歌cpu perf工具)究竟是什么措施?

我试图开始使用Google Perf Tools来分析一些CPU密集型应用程序。 这是一个统计计算,使用`ofstream'将每个步骤转储到一个文件。 我不是C ++专家,所以我很难找到瓶颈。 我的第一回合给出了结果:

Total: 857 samples
     357  41.7%  41.7%      357  41.7% _write$UNIX2003
     134  15.6%  57.3%      134  15.6% _exp$fenv_access_off
     109  12.7%  70.0%      276  32.2% scythe::dnorm
     103  12.0%  82.0%      103  12.0% _log$fenv_access_off
      58   6.8%  88.8%       58   6.8% scythe::const_matrix_forward_iterator::operator*
      37   4.3%  93.1%       37   4.3% scythe::matrix_forward_iterator::operator*
      15   1.8%  94.9%       47   5.5% std::transform
      13   1.5%  96.4%      486  56.7% SliceStep::DoStep
      10   1.2%  97.5%       10   1.2% 0x0002726c
       5   0.6%  98.1%        5   0.6% 0x000271c7
       5   0.6%  98.7%        5   0.6% _write$NOCANCEL$UNIX2003

这是令人惊讶的,因为所有真正的计算都发生在SliceStep :: DoStep中。 “_write $ UNIX2003”(我在哪里可以找出它是什么?)似乎来自编写输出文件。 现在,让我困惑的是,如果我注释掉所有outfile << "text"语句并运行pprof,则95%处于SliceStep::DoStep ,“ SliceStep::DoStep $ UNIX2003”将消失。 然而,我的应用程序没有加速,以总时间来衡量。 整件事速度不到1%。

我错过了什么?

补充:没有outfile <<语句的pprof输出是:

Total: 790 samples
     205  25.9%  25.9%      205  25.9% _exp$fenv_access_off
     170  21.5%  47.5%      170  21.5% _log$fenv_access_off
     162  20.5%  68.0%      437  55.3% scythe::dnorm
      83  10.5%  78.5%       83  10.5% scythe::const_matrix_forward_iterator::operator*
      70   8.9%  87.3%       70   8.9% scythe::matrix_forward_iterator::operator*
      28   3.5%  90.9%       78   9.9% std::transform
      26   3.3%  94.2%       26   3.3% 0x00027262
      12   1.5%  95.7%       12   1.5% _write$NOCANCEL$UNIX2003
      11   1.4%  97.1%      764  96.7% SliceStep::DoStep
       9   1.1%  98.2%        9   1.1% 0x00027253
       6   0.8%  99.0%        6   0.8% 0x000274a6

这看起来像我所期望的,除非我看不到性能有明显提高(在10秒计算中为0.1秒)。 代码基本上是:

ofstream outfile("out.txt");
for loop:
  SliceStep::DoStep()
  outfile << 'result'
outfile.close()

更新:我使用boost :: timer进行计时,从探查器开始和结束的地方开始。 我不使用线程或任何幻想。


从我的评论:

从你的分析器得到的数字表明,如果没有打印报表,程序应该快40%左右。

然而,运行时间几乎保持不变。

显然,其中一项测量结果必定是错误的。 这意味着你必须做更多更好的测量。

首先,我建议从另一个简单的工具开始:时间命令。 这应该让你大致了解你的时间花在哪里。

如果结果仍然不确定,则需要更好的测试用例:

  • 使用更大的问题
  • 测量前先做一次热身。 做一些循环并在之后开始任何测量(在相同的过程中)。

  • 提尔斯坦:全都是用户。 我所做的事情非常简单,我认为......文件全部打开的事实是否意味着什么?

    这意味着剖析器是错误的。

    使用python将100000行打印到控制台的结果如下所示:

    for i in xrange(100000):
        print i
    

    控制台:

    time python print.py
    [...]
    real    0m2.370s
    user    0m0.156s
    sys     0m0.232s
    

    与:

    time python test.py > /dev/null
    
    real    0m0.133s
    user    0m0.116s
    sys     0m0.008s
    

    我的观点是:你的内部测量和时间表明你不会从禁用输出中获得任何收益。 谷歌Perf工具说,你应该。 谁错了?


    _write $ UNIX2003可能指的是write POSIX系统调用,它将输出到终端。 与几乎其他任何东西相比,I / O非常缓慢,所以如果您正在编写一些合理的输出,那么您的程序在这里花费大量时间是有道理的。

    我不确定为什么当你删除输出时你的程序不会加速,但我不能仅仅猜测你提供的信息。 在删除cout语句时,很高兴看到一些代码,甚至是perftools输出。


    Google perftools收集调用堆栈的样本,因此您需要的是对这些样本进行一些查看。

    根据文档,您可以以声明或地址粒度显示调用图。 这应该告诉你你需要知道什么。

    链接地址: http://www.djcxy.com/p/87945.html

    上一篇: What exactly does C++ profiling (google cpu perf tools) measure?

    下一篇: unable to undefined reference to 'pj