GPROF 分析工具的执行时间不准确

GPROF profiling tool is inaccurate execution time

我尝试在 ubuntu 上使用 gprof 测试我的 cpp 代码。

但是我发现了一些错误。

gprof计算执行时间时,最小时间单位为0.01秒

例如,如果我的函数在我的程序中的执行时间是 0.001 甚至更快,gprof 识别为 0 秒。

即使我执行我的函数一千次,它也会这样计算:0/s + 0/s .... + 0/秒 = 0/秒

但实际 运行 时间是 1 秒…

所以,我想知道如何修改最小时间单位或计算准确的执行时间。

请帮助我:)

而且我不需要任何其他分析工具的推荐

这个问题几乎是 inaccuracy in gprof output 的重复,但有一点不同:它似乎试图在错误的地方找到性能瓶颈:

Even if i execute my function thousand time, it calculate like this: 0/s + 0/s …. + 0/s = 0/s

这不是 gprof 的工作方式。 Gprof 在 T 中对程序计数器进行一次采样(通常为 0.01 秒)。它不只是总结时间测量,而是依赖于统计数据。一个需要 1.00 CPU 的程序从未从它应该获得的大约 100 个样本中被抽取的可能性非常低。 80 个样本是可能的,120 个是可能的,0 几乎是不可能的。所以你的问题出在别处。

Gprof 有很多限制,如 inaccuracy in gprof output 所示。真正的问题要么是时间花费在 I/O 中,有一个复杂的相互递归,在一个共享库中,要么它试图重用 gprof 用来对代码进行采样的相同信号。

如果你还执意要改变采样率,那么理论上是可以的,但是太复杂了,不值得。还有have been claims that rewriting the profil() or monstartup() functions. You can override them using linker facilities such as LD_PRELOAD。鉴于 gprof 的局限性,这条路径不值得,而且我看不到任何对实际执行该操作的代码的引用。

这是 Nick Clifton 对此事的引用:

So your choices are:

  1. Alter the profil() function in your OS.
  2. Write your own monstartup() function and find some other way of generating the time samples.

我试图通过破解 SIGPROF 间隔来修改间隔:

void set_interval(double seconds)                                                                                                                                              
{                                                                                                                                                                              
      if (seconds <= 0)                                                                                                                                                          
          return;                                                                                                                                                                
      itimerval prev, next;                                                                                                                                                      
      next.it_value.tv_sec = (uint64_t) seconds;                                                                                                                                 

      next.it_value.tv_usec = (uint64_t)(1000000 * (seconds - next.it_value.tv_sec));                                                                                            
      next.it_interval = next.it_value;                                                                                                                                          
      setitimer(ITIMER_PROF, &next, &prev);                                                                                                                                      
}

在我试过的 Linux 上,main 中的 set_interval(0.1) 确实将时间间隔更改为 1/10 秒(但在 gprof 输出中报告错误)。但是 运行 set_interval(0.001) 对我的机器没有影响,因为最细粒度设置为 10 毫秒。低于 10 毫秒的任何内容都会在内部增加到 10 毫秒。要克服此限制,请阅读 1ms resolution timer under linux recommended way.

这太让人嘲笑了,我强烈建议你放弃这条路线并寻找不同的分析器,或者找出为什么 gprof 不适合你。