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:
- Alter the profil() function in your OS.
- 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 不适合你。
我尝试在 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:
- Alter the profil() function in your OS.
- 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 不适合你。