【程序性能分析利器】Google Perf Tool 和 Valgrind 工具包简介
Google Perf Tools 的安裝和使用
?
- Gperf 工具包包含如下幾個工具:
- 一個優化的內存管理算法—tcmalloc性能優于malloc。
- 一個用于CPU profile的工具,用于檢測程序的性能熱點,這個功能和gprof類似。
- 一個用于堆檢查工具,用于檢測程序在是夠有內存泄露,這個功能和valgrind類似。
- 一個用于Heap profile的工具,用于監控程序在執行過程的內存使用情況。
- 其使用方法如下:
官方代碼:https://github.com/gperftools/gperftools
官方文檔:?http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
官方 github 簡要文檔:https://gperftools.github.io/gperftools
?
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 make make install其安裝版本可自行選擇。在 ./configure 步如果不加生成選項,--prefix=path 不指定安裝的目錄, lib 會默認產生在系統/usr/local/lib,頭文件在 /usr/local/include
?
(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 install2.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查找,然后選擇需要的安裝。
問題二:編譯時打開了./configure –enable-frame-pointers ,這要求被測試的程序在編譯時要加上gcc編譯選項,否則某些多線程程序可能會 core:CCFLAGS=-fno-omit-frame-pointer
?
3.gperftools使用
我們在Google使用的CPU分析器。使用它的過程分為三個部分:將庫鏈接到應用程序,運行代碼以及分析輸出。
3.1? Linking in the Library
要將CPU profiler安裝到可執行文件中,請添加-lprofiler鏈接到可執行文件。(也可能在運行時使用LD_PRELOAD,例如 在添加 % env LD_PRELOAD="/usr/lib/libprofiler.so"
(1)如果是默認的prefix安裝在/usr/local/lib/libprofiler.so
g++ src/test-normal/test-normal.cpp -lprofiler -o test-normal(2)按順序執行下列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
(3)
env LD_PRELOAD=/usr/local/lib/libprofiler.so CPUPROFILE=test-normal.prof ./test-normal可以看到profiler的文件test-normal.prof
?
3.2 Running the Code
此外,還可以將其嵌入到代碼中運行。此處可參考官方文檔。
3.3 Analyzing the Output
需要dot為任何圖形輸出,yum install graphviz, 這里有一些調用pprof的方法。這些將在下面更詳細地描述。
pprof /bin/ls ls.profEnters "interactive" modepprof --text /bin/ls ls.profOutputs one line per procedurepprof --gv /bin/ls ls.profDisplays annotated call-graph via 'gv'pprof --gv --focus=Mutex /bin/ls ls.profRestricts to code paths including a .*Mutex.* entrypprof --gv --focus=Mutex --ignore=string /bin/ls ls.profCode paths including Mutex but not stringpprof --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:1234Outputs one line per procedure for localhost:1234pprof --callgrind /bin/ls ls.profOutputs the call information in callgrind format pprof --pdf test-server test-server.prof > test-server.pdf(1)節點信息
查看 test-server.pdf,在pprof的各種圖形模式中,輸出是帶有時序信息注釋的調用圖每個節點代表一個過程。有向邊指示調用者與被調用者的關系。每個節點的格式如下表所示。
最后一兩行包含時序信息。(分析是通過采樣方法完成的,默認情況下,我們每秒進行100次采樣。因此,輸出中的一個時間單位對應于大約10毫秒的執行時間。)"local"時間是執行指令所花費的時間。直接包含在過程中(以及該過程中內聯的任何其他過程中)。“cumulative”時間是“local”時間與在任何被調者身上花費的時間之和。如果累計時間與當地時間相同,則不會打印。
| Class Name | 類名,非類成員函數此項為空 |
| Method Name | 函數名 |
| local (percentage) | 當前函數直接執行的指令所消耗的CPU時間(包括內聯函數)(百分比) |
| of cumulative (percentage) | 當前函數的local時間及其調用的函數的local時間總和(百分比),如果與local相同,則不顯示 |
(2)邊信息
從一個節點到另一個節點的邊表示調用者與被調用者的關系。每個邊都標有被調用者代表調用者花費的時間。
有向邊:調用者指向被調用者,有向邊上的時間表示被調用者所消耗的CPU時間
?
valgrind的callgrind工具進行多線程性能分析
安裝
Valgrind 的主要作者 Julian Seward 剛獲得了今年的Google-O'Reilly開源大獎之一──Best Tool Maker。讓我們一起來看一下他的作品。Valgrind 是運行在 Linux 上一套基于仿真技術的程序調試和分析工具,它包含一個內核──一個軟件合成的CPU,和一系列的小工具,每個工具都可以完成一項任務──調試,分析,或測試等。Valgrind可以檢測內存泄漏和內存違例,還可以分析cache的使用等,靈活輕巧而又強大,能直穿程序錯誤的心臟,真可謂是程序員的瑞士軍刀。?
一. Valgrind概觀?
Valgrind的最新版是3.2.0,它一般包含下列工具:?
?
1.Memcheck?
最常用的工具,用來檢測程序中出現的內存問題,所有對內存的讀寫都會被檢測到,一切對malloc()/free()/new/delete的調用都會被捕獲。所以,它能檢測以下問題:?
1.對未初始化內存的使用;?
2.讀/寫釋放后的內存塊;?
3.讀/寫超出malloc分配的內存塊;?
4.讀/寫不適當的棧中內存塊;?
5.內存泄漏,指向一塊內存的指針永遠丟失;?
6.不正確的malloc/free或new/delete匹配;?
7,memcpy()相關函數中的dst和src指針重疊。?
這些問題往往是C/C++程序員最頭疼的問題,Memcheck在這里幫上了大忙。?
2.Callgrind?
和gprof類似的分析工具,但它對程序的運行觀察更是入微,能給我們提供更多的信息。和gprof不同,它不需要在編譯源代碼時附加特殊選項,但加上調試選項是推薦的。Callgrind收集程序運行時的一些數據,建立函數調用關系圖,還可以有選擇地進行cache模擬。在運行結束時,它會把分析數據寫入一個文件。callgrind_annotate可以把這個文件的內容轉化成可讀的形式。?
3.Cachegrind?
Cache分析器,它模擬CPU中的一級緩存I1,Dl和二級緩存,能夠精確地指出程序中cache的丟失和命中。如果需要,它還能夠為我們提供cache丟失次數,內存引用次數,以及每行代碼,每個函數,每個模塊,整個程序產生的指令數。這對優化程序有很大的幫助。?
4.Helgrind?
它主要用來檢查多線程程序中出現的競爭問題。Helgrind尋找內存中被多個線程訪問,而又沒有一貫加鎖的區域,這些區域往往是線程之間失去同步的地方,而且會導致難以發掘的錯誤。Helgrind實現了名為“Eraser”的競爭檢測算法,并做了進一步改進,減少了報告錯誤的次數。不過,Helgrind仍然處于實驗階段。?
5. Massif?
堆棧分析器,它能測量程序在堆棧中使用了多少內存,告訴我們堆塊,堆管理塊和棧的大小。Massif能幫助我們減少內存的使用,在帶有虛擬內存的現代系統中,它還能夠加速我們程序的運行,減少程序停留在交換區中的幾率。?
此外,lackey和nulgrind也會提供。Lackey是小型工具,很少用到;Nulgrind只是為開發者展示如何創建一個工具。我們就不做介紹了。?
二. 使用Valgrind?
Valgrind的使用非常簡單,valgrind命令的格式如下:?
一些常用的選項如下:?
選項? :作用?
-h --help? ? ? 顯示幫助信息。?
--version? ? ?顯示valgrind內核的版本,每個工具都有各自的版本。?
-q --quiet? ? ?安靜地運行,只打印錯誤信息。?
-v --verbose? ?打印更詳細的信息。?
--tool= [default: memcheck]? ? 最常用的選項。運行valgrind中名為toolname的工具。如果省略工具名,默認運行memcheck。?
--db-attach= [default: no]? ? ?綁定到調試器上,便于調試錯誤。?
我們通過例子看一下它的具體使用。我們構造一個存在內存泄漏的C程序,如下:??
保存為memleak.c并編譯,然后用valgrind檢測。?
$ gcc -Wall -o memleak memleak.c?
$ valgrind --tool=memcheck ./memleak?
我們可以很清楚地看出,分配和釋放了多少內存,有多少內存泄漏。這對我們查找內存泄漏十分方便。然后我們重新編譯程序并綁定調試器:?
$ gcc -Wall -ggdb -o memleak memleak.c?
$ valgrind --db-attach=yes --tool=memcheck ./memleak?
一出現錯誤,valgrind會自動啟動調試器(一般是gdb):
退出gdb后我們又能回到valgrind繼續執行程序。?
還是用上面的程序,我們使用callgrind來分析一下它的效率:?
$ valgrind --tool=callgrind ./memleak?
Callgrind會輸出很多,而且最后在當前目錄下生成一個文件: callgrind.out.pid。用callgrind_annotate來查看它:?
$ callgrind_annotate callgrind.out.3949?
詳細的信息就列出來了。而且,當callgrind運行你的程序時,你還可以使用callgrind_control來觀察程序的執行,而且不會干擾它的運行。?
再來看一下cachegrind的表現:?
$ valgrind --tool=cachegrind ./memleak?
得到如下信息:?
上面的是指令緩存,I1和L2i緩存,的訪問信息,包括總的訪問次數,丟失次數,丟失率。?
中間的是數據緩存,D1和L2d緩存,的訪問的相關信息,下面的L2緩存單獨的信息。Cachegrind也生成一個文件,名為cachegrind.out.pid,可以通過cg_annotate來讀取。輸出是一個更詳細的列表。Massif的使用和cachegrind類似,不過它也會生成一個名為massif.pid.ps的PostScript文件,里面只有一幅描述堆棧使用狀況的彩圖。?
以上只是簡單的演示了valgrind的使用,更多的信息可以在它附帶的文檔中得到,也可以訪問valgrind的主頁:http://www.valgrind.org。學會正確合理地使用valgrind對于調試程序會有很大的幫助。
?
三、使用valgrind的callgrind工具進行多線程性能分析
valgrind是開源的性能分析利器。 根據它的文檔,可以用它來檢查內存泄漏等問題,還可以用來生成函數的調用圖,就這兩個功能就足夠有吸引力了。
本文主要是介紹如何使用valgrind的callgrind工具進行性能分析。
分析過程
使用callgrind工具生成性能分析數據
命令格式如下:
valgrind --tool=callgrind ./exproxy其中 ./exproxy就是我們要分析的程序。執行完畢后,就會在當前目錄下生成一個文件。文件名為“callgrind.out.進程號”。如,callgrind.out.31113。注意,對于daemon進程的調試,不要通過kill -9方式停止。
如果你調試的程序是多線程,你也可以在命令行中加一個參數 -separate-threads=yes。這樣就會為每個線程單獨生成一個性能分析文件。如下:
valgrind --tool=callgrind --separate-threads=yes ./exproxy生成的文件除了callgrind.out.31113外,還會多出一些子線程的文件。文件名如下:
callgrind.out.31113-01 ? ?callgrind.out.31113-02 ? ?callgrind.out.31113-03
把callgrind生成的性能數據轉換成dot格式數據
可以使用gprof2dot.py腳本,把callgrind生成的性能分析數據轉換成dot格式的數據。方便使用dot把分析數據圖形化。
腳本可以?點此下載?。腳本使用方式如下:
python gprof2dot.py -f callgrind -n10 -s callgrind.out.31113 > valgrind.dot使用dot把數據生成圖片
命令格式如下:
dot -Tpng valgrind.dot -o valgrind.png生成的圖片示例
通過圖形,我們可以很直觀的知道那段程序執行慢,并且了解相關調用關系。
[root@localhost blake]# cat kk.c#include <stdio.h> #include <stdlib.h>void f1() {int i;int *p;for (i = 0; i < 10; i++) {p = malloc(sizeof(int));*p = 10;free(p);} }void f2() {int i;int *p;for (i = 0; i < 20; i++) {p = malloc(sizeof(int));*p = 10;free(p);} }void f3() {int i;int *p;for (i = 0; i < 30; i++) {p = malloc(sizeof(int));*p = 10;free(p);} }int main() {int i;for (i = 0; i < 1000; i++) {f1();f2();f3();}return 0; }[root@localhost blake]# gcc -g kk.c -okk [root@localhost uu]# valgrind --tool=callgrind ./kk --dump-instr=yes --trace-jump=yes ==4798== Callgrind, a call-graph generating cache profiler ==4798== Copyright (C) 2002-2009, and GNU GPL'd, by Josef Weidendorfer et al. ==4798== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==4798== Command: ./kk --dump-instr=yes --trace-jump=yes ==4798== ==4798== For interactive control, run 'callgrind_control -h'. ==4798== ==4798== Events : Ir ==4798== Collected : 11648419 ==4798== ==4798== I refs: 11,648,419 [root@localhost uu]# ll 總用量 44 -rw------- 1 root root 26499 Jul 4 21:01 callgrind.out.4798 -rwxr-xr-x 1 root root 9289 Jul 4 20:48 kk -rw-r--r-- 1 root root 516 Jul 4 20:48 kk.c把callgrind.out.4798傳到 window 7 ,
如果要時行源代碼顯示,KK.C也傳到windows 7 。
用kcachegrind 打開callgrind.out.4798 ,即顯示下面圖
?LINUX: http://kcachegrind.sourceforge.net/html/Home.html
windows: https://sourceforge.net/projects/precompiledbin/files/?source=navbar?
其他相關使用介紹的文章可參見:
https://blog.csdn.net/swartz_lubel/category_6968911.html
https://blog.csdn.net/yutianzuijin/article/details/109731052
總結
以上是生活随笔為你收集整理的【程序性能分析利器】Google Perf Tool 和 Valgrind 工具包简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷入门题P1046、P1047、P14
- 下一篇: Doxygen with Graphvi