Kcachegrind / callgrind неточен для функций диспетчера?
У меня есть код модели, по которому 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
; Callgrinded сvalgrind --tool=callgrind
; кначали сkcachegrind
а такжеqcachegrind-0.7
.
Вот полный callgraph приложения. Все пути к do_J проходят через диспетчер, и это хорошо (do_1 просто скрывается слишком быстро, но он действительно здесь, просто оставлен do_2)
Давайте сосредоточимся наdo_1
и проверьте, кто это назвал (эта картинка неверна):
И это очень странно, я думаю, толькоfirst2
а такжеouter2
называетсяdo_1
но не все.
Это ограничение callgrind / kcachegrind? Как я могу получить точный график вызовов с весами (пропорционально времени выполнения каждой функции, с дочерними элементами и без них)?