我有一個模型代碼,其中kcachegrind/callgrind報告奇怪的結果。這是一種調度功能。調度員從4個地方調用;每個呼叫說,實際do_J
函數來運行,其中(所以first2
將調用僅do_1
和do_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
聯繫電話;與kcachegrind
和qcachegrind-0.7
kcachegrinded。
這裏是應用程序的完整調用圖。到do_J所有路徑經過調度,這是良好(do_1只是牆根的太快了,但它是在這裏真的,只是留給DO_2)
讓我們專注於do_1
和檢查,誰被稱爲它(這張照片是不正確的):
這是很奇怪的,我認爲,只有first2
和outer2
稱爲do_1
但不是全部。
這是callgrind/kcachegrind的限制嗎?我怎樣才能得到準確的權重(與每個功能的運行時間成比例,有沒有孩子)?
有類似的測試與這裏描述的相同問題:[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)「這是我們將看到的:......這些信息不足以知道呼叫的內容樹需要知道顯示真相。「並且有一個解決方法 - callgrind的'--separate-callers = N'選項來記錄callstack的N個槽位。 – osgx
Valgrind文檔有一個有用的選項'--separate-callers = N',[記錄爲callgrind](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