【发布时间】:2014-08-12 16:42:04
【问题描述】:
我有一个 C 程序,它通过函数 pi_calcPiBlock 调用函数 pi_calcPiItem() 600000000 次。因此,为了分析我使用 GNU gprof 的函数所花费的时间。结果似乎是错误的,因为所有调用都归因于main()。此外,调用图没有任何意义:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
61.29 9.28 9.28 pi_calcPiItem
15.85 11.68 2.40 pi_calcPiBlock
11.96 13.49 1.81 _mcount_private
9.45 14.92 1.43 __fentry__
1.45 15.14 0.22 pow
0.00 15.14 0.00 600000000 0.00 0.00 main
Call graph
granularity: each sample hit covers 4 byte(s) for 0.07% of 15.14 seconds
index % time self children called name
<spontaneous>
[1] 61.3 9.28 0.00 pi_calcPiItem [1]
-----------------------------------------------
<spontaneous>
[2] 15.9 2.40 0.00 pi_calcPiBlock [2]
0.00 0.00 600000000/600000000 main [6]
-----------------------------------------------
<spontaneous>
[3] 12.0 1.81 0.00 _mcount_private [3]
-----------------------------------------------
<spontaneous>
[4] 9.4 1.43 0.00 __fentry__ [4]
-----------------------------------------------
<spontaneous>
[5] 1.5 0.22 0.00 pow [5]
-----------------------------------------------
6 main [6]
0.00 0.00 600000000/600000000 pi_calcPiBlock [2]
[6] 0.0 0.00 0.00 600000000+6 main [6]
6 main [6]
-----------------------------------------------
这是一个错误还是我必须以某种方式配置程序?
<spontaneous> 是什么意思?
编辑(为您提供更多见解)
代码都是关于计算圆周率的:
#define PI_BLOCKSIZE (100000000)
#define PI_BLOCKCOUNT (6)
#define PI_THRESHOLD (PI_BLOCKSIZE * PI_BLOCKCOUNT)
int32_t main(int32_t argc, char* argv[]) {
double result;
for ( int32_t i = 0; i < PI_THRESHOLD; i += PI_BLOCKSIZE ) {
pi_calcPiBlock(&result, i, i + PI_BLOCKSIZE);
}
printf("pi = %f\n",result);
return 0;
}
static void pi_calcPiBlock(double* result, int32_t start, int32_t end) {
double piItem;
for ( int32_t i = start; i < end; ++i ) {
pi_calcPiItem(&piItem, i);
*result += piItem;
}
}
static void pi_calcPiItem(double* piItem, int32_t index) {
*piItem = 4.0 * (pow(-1.0,index) / (2.0 * index + 1.0));
}
这就是我得到结果的方式(在 Cygwin 的帮助下在 Windows 上执行):
> gcc -std=c99 -o pi *.c -pg -fno-inline-small-functions
> ./pi.exe
> gprof.exe pi.exe
【问题讨论】:
-
代码?您使用什么命令行来查看结果?
-
@CDahn 我刚刚添加了您要的内容。
-
函数内联是标准的 C 编译器优化。您无法获取不再存在的函数的函数调用计数。
-
@HansPassant 因此我只使用了
-fno-inline-small-functions参数来避免内联(因此,编辑了上面的描述)。 但是:gprof 的输出没有任何变化。 -
使用 -S 再次检查您的假设。确实会有一个点,修补优化器设置开始产生无用的配置文件结果。您可以通过禁用内联来克服它。
标签: c profiling profiler gprof