Google Perf Tools安裝以及使用

Google Performance Tools安裝以及使用

這邊文章都記錄在github:https://github.com/NIGHTFIGHTING/gperftools-tutorial
一個優化的內存管理算法—tcmalloc性能優於malloc。
一個用於CPU profile的工具,用於檢測程序的性能熱點,這個功能和gprof類似。
一個用於堆檢查工具,用於檢測程序在是夠有內存泄露,這個功能和valgrind類似。
一個用於Heap profile的工具,用於監控程序在執行過程的內存使用情況。

1.使用其提供的內存管理函數---TC Malloc:
       gcc [...] -ltcmalloc  
2.使用其堆內存檢查工具---Heap Checker:
       gcc [...] -o myprogram -ltcmalloc
       HEAPCHECK=normal ./myprogram   

3.使用Heap Profiler:
      gcc [...] -o myprogram -ltcmalloc
      HEAPPROFILE=/tmp/netheap ./myprogram  

4.使用Cpu Profiler:
      gcc [...] -o myprogram -lprofiler
      CPUPROFILE=/tmp/profile ./myprogram

代碼:https://github.com/gperftools/gperftools
官方文檔:
http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
https://gperftools.github.io/gperftools/cpuprofile.html
http://goog-perftools.sourceforge.net/doc/cpu_profiler.html
https://github.com/gperftools/gperftools/wiki

1.安裝libunwind

(1)源碼安裝libunwind

wget https://github.com/libunwind/libunwind/archive/v0.99.tar.gz  
tar -xvf v0.99.tar.gz  
cd libunwind-0.99  
autoreconf --force -v --install  
./configure --prefix=gperftools-tutorial/output   
make   
make install  

這裏我安裝產出在https://github.com/NIGHTFIGHTING/gperftools-tutorial/tree/master/output 這個目錄
如果prefix不指定安裝的目錄,lib會產生在系統/usr/local/lib,頭文件在/usr/local/include
我已經下載好的安裝包在https://github.com/NIGHTFIGHTING/gperftools-tutorial/tree/master/gperftools

(2)yum安裝

yum search libunwind # 查找,然後選擇需要的安裝  
yum install libunwind-devel.x86_64  

2.安裝gperftools

源碼安裝google-perf-tools/gperftools

wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.6.1/gperftools-2.6.1.tar.gz  
tar -xvf  gperftools-2.6.1.tar.gz # 解壓  
./configure --prefix=gperftools-tutorial/output   
make   
make install  

這裏我安裝產出在https://github.com/NIGHTFIGHTING/gperftools-tutorial/tree/master/output 這個目錄
如果prefix不指定安裝的目錄,lib會產生在系統/usr/local/lib,頭文件在/usr/local/include
我已經下載好的安裝包在https://github.com/NIGHTFIGHTING/gperftools-tutorial/tree/master/gperftools

2.1問題

安裝時可能出現configure: WARNING: No frame pointers and no libunwind. Using experimental backtrace capturing via libgcc.Expect crashy cpu profiler。
是因爲沒有安裝libunwind。在gperftools工具的INSTLL例有說明,64位系統需要安裝。使用yum search libunwind查找,
然後選擇需要的安裝。

2.2問題

編譯時打開了./configure –enable-frame-pointers ,這要求被測試的程序在編譯時要加上gcc編譯選項,否則某些多線程程序可能會 core:CCFLAGS=-fno-omit-frame-pointer

3.gperftools使用

我們在Google使用的CPU分析器。使用它的過程分爲三個部分:將庫鏈接到應用程序,運行代碼以及分析輸出

3.1Linking in the Library

要將CPU profiler安裝到可執行文件中,請添加-lprofiler鏈接到可執行文件。(也可能在運行時使用LD_PRELOAD,例如 在添加 % env LD_PRELOAD="/usr/lib/libprofiler.so" ,但不一定建議這樣做。)
這並沒有打開CPU性能分析; 它只是插入代碼。因此,-lprofiler在開發過程中始終始終鏈接到二進制文件是可行的 。這就是我們在Google所做的。(但是,由於任何用戶都可以通過設置環境變量來打開探查器,因此不一定建議將鏈接profiler的二進制文件安裝到運行中的生產系統中。)
比如:

(1)使用prefix產出的lib

g++ src/test-normal/test-normal.cpp -I output/include/ output/lib/libprofiler.a -o test-normal   

(2)如果是默認的prefix安裝在/usr/local/lib/libprofiler.so

g++ src/test-normal/test-normal.cpp -lprofiler -o test-normal  

(3)按順序執行下列shell

   export LD_PRELOAD="/usr/local/lib/libprofiler.so"  
   g++ src/test-normal/test-normal.cpp -o test-normal  
   env CPUPROFILE=test-normal.prof ./test-normal  

可以看到profiler的文件test-normal.prof

(4)

   env LD_PRELOAD=/usr/local/lib/libprofiler.so CPUPROFILE=test-normal.prof ./test-normal  

可以看到profiler的文件test-normal.prof

3.2Running the Code

(1)將環境變量CPUPROFILE定義爲將概要文件轉儲到的文件名。例如,如果您有一個/bin/ls與libprofiler鏈接的版本 ,則可以運行:

    env CPUPROFILE=ls.prof /bin/ls
    env CPUPROFILE=test-normal.prof ./test-normal # 我們可以接着3.1(1)或者3.1(2)或者3.1(3)繼續執行  

可以看到profiler的文件test-normal.prof

(2)除了定義環境變量CPUPROFILE外,您還可以定義CPUPROFILESIGNAL。這樣可以通過您指定的信號號來控制性能分析。在正常操作下,這個信號編號必須沒有被程序中使用過。在內部,它充當由信號觸發的開關,默認情況下處於關閉狀態。例如,如果您有一個/bin/chrome與libprofiler鏈接的版本 ,則可以運行:

    env CPUPROFILE=chrome.prof CPUPROFILESIGNAL=12 /bin/chrome &
    killall -12 chrome # 然後,您可以觸發分析以開始
    killall -12 chrome # 然後,在一段時間後,您可以告訴它停止以生成profile文件
[2.1]測試test-server
    g++ src/test-server/test-server.cpp -lprofiler -o test-server
    env CPUPROFILE=test-server.prof CPUPROFILESIGNAL=12 ./test-server>log 2>&1 &
    killall -12 test-server
    killall -12 test-server #看見生成的profiler文件test-server.prof.0
[2.2]測試test-server
    export CPUPROFILE=test-server.prof CPUPROFILESIGNAL="12" LD_PRELOAD="/usr/local/lib/libprofiler.so"
    g++ src/test-server/test-server.cpp -o test-server
    killall -12 test-server
    killall -12 test-server #看見生成的profiler文件test-server.prof.0
[xiaoju@flliuqi gperftools-tutorial]$ pprof --text test-server test-server.prof.0
Using local file test-server.
Using local file test-server.prof.0.
Total: 1616 samples
     817  50.6%  50.6%     1616 100.0% loopop
     799  49.4% 100.0%      799  49.4% loopop_callee
       0   0.0% 100.0%     1616 100.0% __libc_start_main
       0   0.0% 100.0%     1616 100.0% _start
       0   0.0% 100.0%     1616 100.0% main

(3)在您的代碼中,將您要分析的代碼括在對ProfilerStart()和的調用中 ProfilerStop()。(這些函數在<gperftools/profiler.h>中聲明。) ProfilerStart()將使用profiler文件名[profile-filename]作爲參數。

    g++ src/test-normal/test-normal-profiler.cpp -lprofiler -o test-normal
    ./test-normal # 會產生profiler文件test-normal.prof
    g++ src/test-server/test-server-profiler.cpp -lprofiler -o test-server
    ./test-server >log 2>&1 &
    kill -SIGUSR1 `ps -ef | grep test-server | grep -v grep | awk '{print $2}'`    # 或者使用killall -10 test-server(kill -l可以查看信號的編號)
    kill -SIGUSR2 `ps -ef | grep test-server | grep -v grep | awk '{print $2}'`    # 或者使用killall -12 test-server
    #得到profiler文件test-server.prof

3.3Analyzing the Output

需要dot爲任何圖形輸出,yum install graphviz,這裏有一些調用pprof的方法。這些將在下面更詳細地描述。

    pprof /bin/ls ls.prof
                          Enters "interactive" mode
    pprof --text /bin/ls ls.prof
                          Outputs one line per procedure
    pprof --gv /bin/ls ls.prof
                          Displays annotated call-graph via 'gv'
    pprof --gv --focus=Mutex /bin/ls ls.prof
                          Restricts to code paths including a .*Mutex.* entry
    pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
                          Code paths including Mutex but not string
    pprof --list=getdir /bin/ls ls.prof
                          (Per-line) annotated source listing for getdir()
    pprof --disasm=getdir /bin/ls ls.prof
                          (Per-PC) annotated disassembly for getdir()
    pprof --text localhost:1234
                          Outputs one line per procedure for localhost:1234
    pprof --callgrind /bin/ls ls.prof
                       Outputs the call information in callgrind format
    pprof --pdf test-server test-server.prof > test-server.pdf

(1)節點信息

查看test-server.pdf,在pprof的各種圖形模式中,輸出是帶有時序信息註釋的調用圖
每個節點代表一個過程。有向邊指示調用者與被調用者的關係。每個節點的格式如下:
Class Name
Method Name
local (percentage)
of cumulative (percentage)
最後一兩行包含時序信息。(分析是通過採樣方法完成的,默認情況下,我們每秒進行100次採樣。因此,輸出中的一個時間單位對應於大約10毫秒的執行時間。)"local"時間是執行指令所花費的時間。直接包含在過程中(以及該過程中內聯的任何其他過程中)。“cumulative”時間是“local”時間與在任何被叫者身上花費的時間之和。如果累計時間與當地時間相同,則不會打印。

字段名 描述
Class Name 類名,非類成員函數此項爲空
Method Name 函數名
local (percentage) 當前函數直接執行的指令所消耗的CPU時間(包括內聯函數)(百分比)
of cumulative (percentage) 當前函數的local時間及其調用的函數的local時間總和(百分比),如果與local相同,則不顯示

(2)邊信息

從一個節點到另一個節點的邊表示調用者與被調用者的關係。每個邊都標有被調用者代表調用者花費的時間。
有向邊:調用者指向被調用者,有向邊上的時間表示被調用者所消耗的CPU時間

4.參考

https://blog.csdn.net/10km/article/details/83820080
https://blog.csdn.net/dolphin98629/article/details/80932848
https://www.jianshu.com/p/8b996698e2e3
https://www.iteye.com/blog/xiaotaoge-1565059
https://www.cnblogs.com/foxmailed/archive/2012/04/08/2437207.html
https://www.cnblogs.com/Lipp/archive/2012/05/28/2521382.html
https://www.cnblogs.com/dylancao/p/7683960.html
https://blog.csdn.net/weixin_41376894/article/details/78793321
https://www.cnblogs.com/lenolix/archive/2010/12/13/1904868.html
https://www.kancloud.cn/subin/blog/619133

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章