我有一个模型代码,kcachegrind/callgrind 报告了奇怪的结果。这是一种调度程序功能。调度员从 4 个地方调用;每个调用都说明要运行哪个实际do_J
函数(因此first2
只会调用do_1
等等do_2
)
源代码(这是实际代码的模型)
#define N 1000000
int a[N];
int do_1(int *a) { int i; for(i=0;i<N/4;i++) a[i]+=1; }
int do_2(int *a) { int i; for(i=0;i<N/2;i++) a[i]+=2; }
int do_3(int *a) { int i; for(i=0;i<N*3/4;i++) a[i]+=3; }
int do_4(int *a) { int i; for(i=0;i<N;i++) a[i]+=4; }
int dispatcher(int *a, int j) {
if(j==1) do_1(a);
else if(j==2) do_2(a);
else if(j==3) do_3(a);
else do_4(a);
}
int first2(int *a) { dispatcher(a,1); dispatcher(a,2); }
int last2(int *a) { dispatcher(a,4); dispatcher(a,3); }
int inner2(int *a) { dispatcher(a,2); dispatcher(a,3); }
int outer2(int *a) { dispatcher(a,1); dispatcher(a,4); }
int main(){
first2(a);
last2(a);
inner2(a);
outer2(a);
}
编译gcc -O0
; 用valgrind --tool=callgrind
; kcache 用kcachegrind
和研磨qcachegrind-0.7
。
这是应用程序的完整调用图。do_J 的所有路径都通过调度程序,这很好(do_1 被隐藏得太快了,但它真的在这里,只是留给 do_2)
让我们重点do_1
看看,谁叫它(这张图是不正确的):
这很奇怪,我认为,只有first2
和outer2
调用do_1
但不是全部。
这是 callgrind/kcachegrind 的限制吗?如何获得带有权重的准确调用图(与每个函数的运行时间成正比,无论有无子函数)?