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? Как я могу получить точный график вызовов с весами (пропорционально времени выполнения каждой функции, с дочерними элементами и без них)?

Ответы на вопрос(1)

Ваш ответ на вопрос