Kcachegrind / callgrind es inexacto para las funciones del despachador?

Tengo un código modelo en el que kcachegrind / callgrind informa resultados extraños. Es una especie de función de despachador. El despachador se llama desde 4 lugares; cada llamada dice, que @ redo_J función para ejecutar (por lo que elfirst2 solo llamará ado_1 ydo_2 y así

Source (este es un modelo de código real)

#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);
}

Compilado congcc -O0; Callgrinded convalgrind --tool=callgrind; kcachegrinded conkcachegrind yqcachegrind-0.7.

Aquí hay un callgraph completo de la aplicación. Todos los caminos para hacer_J pasan por el despachador y esto es bueno (el do_1 simplemente se oculta como demasiado rápido, pero realmente está aquí, solo queda para hacer_2)

Vamos a centrarnos endo_1 y compruebe quién lo llamó (esta imagen es incorrecta):

Y esto es muy extraño, creo, solofirst2 youter2 llamadodo_1 pero no todos

¿Es una limitación de callgrind / kcachegrind? ¿Cómo puedo obtener un callgraph preciso con pesos (proporcional al tiempo de ejecución de cada función, con y sin sus hijos)?

Respuestas a la pregunta(1)

Su respuesta a la pregunta