Kcachegrind / callgrind неточен для функций диспетчера? - PullRequest
4 голосов
/ 20 сентября 2011

У меня есть код модели, по которому 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; kcachegrinded с kcachegrind и qcachegrind-0.7.

Вот полный callgraph приложения. Все пути к do_J проходят через диспетчер, и это хорошо (do_1 просто скрывается слишком быстро, но он действительно здесь, просто оставлен до do_2)

Full

Давайте сосредоточимся на do_1 и проверим, кто его вызвал (эта картинка неверна):

enter image description here

И это очень странно, я думаю, только first2 и outer2 называется do_1, но не все.

Это ограничение callgrind / kcachegrind? Как я могу получить точный график вызовов с весами (пропорционально времени выполнения каждой функции, с дочерними элементами и без них)?

1 Ответ

1 голос
/ 30 октября 2011

Да, это ограничение формата callgrind. Это не хранит полный след; он хранит только информацию о родительских и дочерних вызовах.

Существует проект google-perftools с профайлером процессора pprof / libprofiler.so, http://google -perftools.googlecode.com / svn / trunk / doc / cpuprofile.html . libprofiler.so может получить профиль с calltraces, и он будет хранить каждое событие трассировки с полной обратной трассировкой. pprof - конвертер вывода libprofile в графические форматы или в формат callgrind. При полном просмотре результат будет таким же, как в kcachegrind; но если вы сосредоточитесь на какой-то функции, например do_1 с использованием фокуса опции pprof; он покажет точное дерево вызовов, когда сфокусировано на функции.

...