callgrind工具的使用方法
callgrind使用cachegrind的統計資訊Ir(I cache reads,也就是一條指令執行的次數)來統計程式中函數的調用情況。
Callgrind = cachegrind + function call graph information.
Cachegrind是一個性能分析工具,可以通過定位源代碼來剖析cache misses,cache misses 越低表明程式效率越高。
3.3.1 收集程式的統計資訊
callgrind使用動態檢測方法,可以直接對可執行程式進行統計,不需要特別指定編譯選項。命令如下:
valgrind --tool=callgrind [callgrind options] your-program [program options]
在程式運行過程中可以用callgrind_control命令來即時的統計資訊
3.3.2 查看統計資訊
程式結束後callgrind會在可執行程式所在的檔夾生成統計資訊檔callgrind.out.<pid>。我們可以使用callgrind_annotate [options] callgrind.out.<pid>查看統計資訊。
options中有特點的兩個是:
1) --inclusive=yes:不但分別統計每個語句的執行次數,還把調用關係計算進去,比如函數foo調用了bar,foo的代價中會加入bar的代價。
2) --tree=both:顯示調用和被調用關係,可以選擇no,call,callee,就是說可以不顯示或者只顯示調用,或只顯示被調用。
推薦使用的選項:
--auto=yes:會自動將統計資訊和源碼關聯。
使用callgrind進行統計:
valgrind --tool=callgrind ./CLI 這裏會將結果自動導出到callgrind.out.<pid>這個檔中。
但是callgrind.out.<pid>這個檔人難以看懂,可以通過callgrind_annotate查看統計資訊:
callgrind_annotate --auto=yes callgrind.out.<pid> > CLIvalgrind.log 由於結果會很多,最好將結果用重定向的方式定向一下,這裏定向到CLIvalgrind.log。
由於這種類比統計需要消耗大量的資源,所以callgrind只統計次數而不去統計時間。
統計結果中
3,000 printf("Hello World!\n");
606,751 => ???:printf (1000x)
左側的數字606,751表示該條代碼執行所用的指令數,右側括弧中的數位1000x代表函數的調用次數。
另一段使用--tree=both標記的代碼:
統計資訊片段:(根據標紅線的地方可以判斷調用關係和代價)
3,250 < /home2/syang/test/test.c:bar (10x) [/home2/syang/test/test] 被bar調用帶來的代價
4,310 < /home2/syang/test/test.c:main (10x) [/home2/syang/test/test] 被main調用帶來的代價
7,560 * /home2/syang/test/test.c:foo [/home2/syang/test/test] foo的總代價
6,705 > ???:puts (20x) [/lib64/libc-2.5.so] 調用puts給puts帶來的代價
735 > ???:_dl_runtime_resolve (1x) [/lib64/ld-2.5.so] ...