google開源的C++性能分析工具 - gperftools
gperftools是Google提供的一套工具,其中的一個功能是CPU profiler,用于分析程序性能,找到程序的性能瓶頸。
安裝
64位操作系統需要安裝libunwind,官方推薦版本是libunwind-0.99-beta
安裝過程:./configure [--disable-shared] &&make && make install
Graphviz是一個由AT&T實驗室啟動的開源工具包,用于繪制DOT語言腳本描述的圖形,gperftools依靠此工具生成圖形分析結果。
安裝命令:yum install graphviz
1.編譯libunwind庫
因為使用的是X86_64的Linux系統,因此需要安裝libunwind庫。
安裝方法很簡單,常見的configure,make,make install的套路。
tarxvzf libunwind-0.99-beta.tar.gz
cd libunwind-0.99-beta
./configure
make
makeinstall
因為默認的libunwind安裝在/usr/local/lib目錄下,需要將這個目錄添加到系統動態庫緩存中。
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
/sbin/ldconfig
libunwind的最新版本是1.0.1,那為什么
不選擇最新版本呢?google
perftools的INSTALL文件中給了說明。版本低于0.99-beta的libunwind與preftools一起工作可能不正常,但是高于
0.99-beta的版本中可能包含一些與perftools不兼容的代碼(因為libunwind會調用malloc,可能會導致死鎖)。
libunwind在X86_64平臺上和perftools有不少問題,不過不會影響核心的tcmalloc庫,但是會影響perftools中的工
具,例如cpu-profiler,heap-checker,heap-profiler。
2.編譯google-perftools
因為我們只需要tcmalloc功能,因此不編譯google-perftools中的其他工具。
tarxvzf google-perftools-1.9.1.tar.gz
cd google-perftools-1.9.1
./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --enable-minimal--disable-dependency-tracking
make
makeinstall
/sbin/ldconfig
用法
1.目標程序中引入頭文件<google/profiler.h>,鏈接libprofiler庫,64位操作系統同時鏈接libunwind庫,在需要分析代碼的起點和終點調用ProfilerStart()函數和ProfilerStop()函數
2.編譯鏈接,運行程序
分析輸出
pprof腳本用于分析profile文件并輸出結果,包括文本和圖形兩種輸出風格。
例如:demo是目標程序,my.prof是profile文件
生成文本風格結果:pprof --text ./demo my.prof >profile.txt
生成圖形風格結果:pprof --pdf ./demo my.prof > profile.pdf
對于一個函數的CPU使用時間分析,分為兩個部分:
1.整個函數消耗的CPU時間,包括函數內部其他函數調用所消耗的CPU時間
2.不包含內部其他函數調用所消耗的CPU時間(內聯函數除外)
關于文本風格輸出結果
關于圖形風格輸出結果
1.節點
每個節點代表一個函數,節點數據格式:
local時間是函數直接執行的指令所消耗的CPU時間(包括內聯函數);性能分析通過抽樣方法完成,默認是1秒100個樣本,一個樣本是10毫秒,即時間單位是10毫秒;
cumulative時間是local時間與其他函數調用的總和;
如果cumulative時間與local時間相同,則不打印cumulative時間項。
2.有向邊
調用者指向被調用者,有向邊上的時間表示被調用者所消耗的CPU時間
示例
代碼如下,可以看出,CPU消耗集中在func1()和func2()兩個函數,func2()消耗時間約為func1()的兩倍。
#include <google/profiler.h>
#include <iostream>
using namespace std;
void func1() {
int i = 0;
while (i < 100000) {
++i;
}
}
void func2() {
int i = 0;
while (i < 200000) {
++i;
}
}
void func3() {
for (int i = 0; i < 1000; ++i) {
func1();
func2();
}
}
int main(){
ProfilerStart("my.prof"); // 指定所生成的profile文件名
func3();
ProfilerStop(); // 結束profiling
return 0;
}
然后編譯鏈接運行,使用pprof生成分析結果
g++-o demo demo.cpp -lprofiler -lunwind
pprof--text ./demo my.prof > output.txt
pprof--pdf ./demo my.prof > output.pdf
查看分析結果,程序是122個時間樣本,其中,func1()是40個時間樣本,約為400毫秒;func2()是82個時間樣本,約為820毫秒。
Total: 122 samples
82 67.2% 67.2% 82 67.2% func2
40 32.8% 100.0% 40 32.8% func1
0 0.0% 100.0% 122 100.0% __libc_start_main
0 0.0% 100.0% 122 100.0% _start
0 0.0% 100.0% 122 100.0% func3
0 0.0% 100.0% 122 100.0% main
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!