2011-09-20 4 views
3

kcachegrind/callgrind가 이상한 결과를보고하는 모델 코드가 있습니다. 일종의 디스패처 기능입니다. 발송자는 4 곳에서 호출됩니다. 각 호출은 실제 do_J 기능을 실행하기 위해 (때문에 first2do_1do_2 등 호출)Kcachegrind/callgrind가 디스패처 기능에 대해 정확하지 않습니까?

#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로 전화를 걸었다. kcachegrindqcachegrind-0.7으로 kcachegrinded.

다음은 애플리케이션의 전체적인 콜 그래프입니다. do_J에 대한 모든 경로가 디스패처 통해 이동이 좋다라는 사람,

Full

do_1에 초점을 수 있습니다 및 확인합니다 (do_1가 너무 빨리 고용 했지,하지만 정말 여기에, 그냥 do_2 왼쪽) 그것은 (이 그림은 잘못된 것입니다) :

enter image description here

을 그리고 이것은 단지 first2outer2 전부는 아니지만 do_1라고, 나는 생각한다, 매우 이상하다.

callgrind/kcachegrind의 제한 사항입니까? 가중치를 가진 정확한 콜 그래프를 얻으려면 어떻게해야합니까? (모든 기능의 실행 시간에 상관없이, 차일드 ​​유무와 상관없이)?

답변

1

예, 이것은 콜그라 인 형식의 제한 사항입니다. 전체 추적을 저장하지 않습니다. 부모 - 자식 호출 정보 만 저장합니다.

pprof/libprofiler.so CPU 프로파일 러가있는 google-perftools 프로젝트가 있습니다 (http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html). libprofiler.so은 calltraces로 프로파일을 얻을 수 있으며 전체 백 트레이스와 함께 모든 추적 이벤트를 저장합니다. pprof은 libprofile의 그래픽 형식 또는 callgrind 형식으로의 출력 변환기입니다. 전체보기에서 결과는 kcachegrind와 동일합니다. 하지만 일부 기능 (예 : pprof의 옵션 포커스를 사용하여 do_1; 그것은 기능에 초점을 맞출 때 정확한 calltree를 보여줄 것이다.

+1

비슷한 문제가 여기에 설명되어 있습니다. [http://www.yosefk.com/blog/how-profilers-lie-the-cases-of-gprof-and-kcachegrind.html] (http : // /www.yosefk.com/blog/how-profilers-lie-the-cases-of-gprof-and-kcachegrind.html) "여기에 우리가 보게 될 것이 있습니다 : ...이 정보는 전화가 무엇인지 알기에 충분하지 않습니다. 나무는 진실을 보여줄 필요가있다. " 그리고 해결 방법이 있습니다 - callstring의 N 슬롯을 기록하기위한 callgrind의'--separate-callers = N' 옵션 – osgx

+0

Valgrind 문서는 callgrind에 대한 유용한 옵션 인'--separate-callers = N' (http : //)을 가지고 있습니다. valgrind.org/docs/manual/cl-manual.html) http://valgrind.org/docs/manual/cl-manual.html#cl-manual.cycles (6.2.4주기 회피) 및 http : // /valgrind.org/docs/manual/cl-manual.html#cl-manual.options.separation (6.3.4 원가 요소 분리 옵션) – osgx