Callgrind是一款和gprof類似的性能分析工具,與gprof不同的是它不需要在編譯源碼時附加特殊選項,但推薦加上調試選項。Callgrind使用cachegrind的統計信息Ir(I cache reads,即一條指令執行的次數)來統計程序中函數的調用情況,建立函數調用關系圖,還可以有選擇地進行cache模擬。在運行結束時,它會把分析數據寫入一個文件,callgrind_annotate可以把這個文件的內容轉化成可讀的形式。
一、基本語法
Callgrind語法格式如下:
valgrind --tool=callgrind [callgrind options] your-program [program options]
可以如下來使用valgrind啟動后台服務進程:
#valgrind --tool=callgrind --separate-threads=yes ./haproxy -f haproxy.cfg
其中,--tool=callgrind表示使用valgrind提供的性能分析功能,--separate-threads=yes表示要查看多線程相關數據。
在程序運行過程中可以用callgrind_control將性能數據dump到指定目錄下(可以使用callgrind_control -h查看幫助信息),比如:
#callgrind_control -d -w /usr/local/haproxy
上面命令會將所有線程的性能數據dump到目錄/usr/local/haproxy下生成的callgrind.out.pid文件中。
我們可以使用callgrind_annotate [options] callgrind.out.pid查看性能數據,其中,options選項參數詳細信息如下:
(1)--inclusive=yes:不但分別統計每個語句的執行次數,還把調用關系計算進入,比如函數foo調用了bar,那么foo的代價中會加入bar的代價。
(2)--tree=both:顯示調用關系。
(3)--auto=yes:會自動將統計信息和源碼關聯。
單純查看性能數據,可以如下:
#callgrind_annotate --inclusive=yes callgrind.out.pid
既要查看性能數據,又要查看調用關系,可以如下:
#callgrind_annotate --inclusive=yes --tree=both callgrind.out.pid
二、使用實例
下面將提供一段簡單的代碼來演示如何使用callgrind來分析性能,具體代碼如下:
編譯代碼並使用callgrind進行性能統計:
此時,在當前目錄下能看到生成了callgrind.out.23588的性能數據文件。當然如果在編譯代碼時想生成匯編代碼,那么可以如下:
#g++ -S -g -o test test.cpp
不錯如此一來,則就會在當前目錄下生成一大批callgrind.out.xxxxx的性能數據文件,在此不表匯編的事情。
接下來分別用前文提到三種方式來查看統計信息:
(1)--auto=yes
#callgrind_annotate --auto=yes callgrind.out.23588 > log
#vi log
由於這種模擬統計需要消耗大量的資源,所以callgrind只統計次數而不統計時間,上面只是截取了統計分析結果的一部分,左側數字表示該條代碼執行所用的指令數。
(2)--tree=both
#callgrind_annotate --tree=both callgrind.out.23588 > log
#vi log

上圖中左側數字表示調用帶來的代價。
(3)--inclusive=yes
#callgrind_annotate --inclusive=yes callgrind.out.23588 > log
#vi log

像上圖這般分析比較常見。
