原文地址:
http://apps.hi.baidu.com/share/detail/5908917
gprof介紹
gprof是GNU profiler工具。可以顯示程式啟動並執行“flat profile”,包括每個函數的調用次數,每個函數消耗的處理器時間。也可以顯示“調用圖”,包括函數的調用關係,每個函數調用花費了多少時間。還可以顯示“注釋的原始碼”,是程式原始碼的一個複本,標記有程式中每行代碼的執行次數。
基本用法:
1. 使用-pg選項編譯和連結你的應用程式。
2. 執行你的應用程式,使之運行完成後產生供gprof分析的資料檔案(預設是gmon.out)。
3. 使用gprof程式分析你的應用程式產生的資料,例如:gporf a.out gmon.out。
舉例
gcc -Wall -pg -o test test.c //程式檔案名稱 test.c 編譯時間使用 -pg
現在我們可以再次運行test,並使用我們前面使用的測試資料。這次我們啟動並執行時候,test啟動並執行分析資料會被搜集並儲存在'gmon.out'檔案中,我們可以通過運行 ' gprof test '來查看結果。
./test
gprof test
gprof 實現原理:
gprof並不神奇,在編譯和連結程式的時 候(使用 -pg 編譯和連結選項),gcc 在你應用程式的每個函數中都加入了一個名為mcount(or“_mcount”, or“__mcount”)的函數,也就是說-pg編譯的應用程式裡的每一個函數都會調用mcount, 而mcount會在記憶體中儲存一張函數調用圖,並通過函數呼叫堆疊的形式尋找子函數和父函數的地址。這張調用圖也儲存了所有與函數相關的調用時間,調用次數等等的所有資訊。
程式運行結束後,會在程式退出的路徑下產生一個 gmon.out檔案。這個檔案就是記錄並儲存下來的監控資料。可以通過命令列方式的gprof或圖形化的Kprof來解讀這些資料並對程式的效能進行分析。
另外,如果想查看庫函數的profiling,需要在編譯是再加入“-lc_p”編譯參數代替“-lc”編譯參數,這樣程式會連結libc_p.a 庫,才可以產生庫函數的profiling資訊。如果想執行一行一行的profiling,還需要加入“-g”編譯參數。
gprof產生的資訊
% the percentage of the total running time of the
time program used by this function.
函數使用時間占所有時間的百分比。
cumulative a running sum of the number of seconds accounted
seconds for by this function and those listed above it.
函數和上列函數累計執行的時間。
self the number of seconds accounted for by this
seconds function alone. This is the major sort for this
listing.
函數本身所執行的時間。
calls the number of times this function was invoked, if
this function is profiled, else blank.
函數被調用的次數
self the average number of milliseconds spent in this
ms/call function per call, if this function is profiled,
else blank.
每一次調用花費在函數的時間microseconds。
total the average number of milliseconds spent in this
ms/call function and its descendents per call, if this
function is profiled, else blank.
每一次調用,花費在函數及其衍生函數的平均時間microseconds。
name the name of the function. This is the minor sort
for this listing. The index shows the location of
the function in the gprof listing. If the index is
in parenthesis it shows where it would appear in
the gprof listing if it were to be printed.
函數名
更多詳細介紹
1. 在記憶體中分配一些記憶體,儲存程式執行期間的統計資料
2. 在GCC使用-pg選項編譯後,gcc會在程式的入口處(main 函數之前)調用
void monstartup(lowpc, highpc)
在每個函數的入口處調用
void _mcount()
在程式退出時(在 atexit () 裡)調用
void _mcleanup()
* monstartup:負責初始化profile環境,分配記憶體空間
* _mcount: 記錄每個函數代碼的caller和callee的位置
* _mcleanup:清除profile環境,儲存結果資料為gmon.out,供gprof分析結果
3.在_mcount函數中跟蹤程式的執行狀況,記錄程式碼的執行次數,時間等資料。
常用的gprof命令選項:
-b 不再輸出統計圖表中每個欄位的詳細描述。
-p 只輸出函數的調用圖(Call graph的那部分資訊)。
-q 只輸出函數的時間消耗列表。
-e Name 不再輸出函數Name 及其子函數的調用圖(除非它們有未被限制的其它父函數)。可以給定多個 -e 標誌。一個 -e 標誌只能指定一個函數。
-E Name 不再輸出函數Name 及其子函數的調用圖,此標誌類似於 -e 標誌,但它在總時間和百分比時間的計算中排除了由函數Name 及其子函數所用的時間。
-f Name 輸出函數Name 及其子函數的調用圖。可以指定多個 -f 標誌。一個 -f 標誌只能指定一個函數。
-F Name 輸出函數Name 及其子函數的調用圖,它類似於 -f 標誌,但它在總時間和百分比時間計算中僅使用所列印的常式的時間。可以指定多個 -F 標誌。一個 -F 標誌只能指定一個函數。-F 標誌覆蓋 -E 標誌。
-z 顯示使用次數為零的常式(按照調用計數和累積時間計算)。
使用注意:
1) 一般gprof只能查看使用者函數資訊。如果想查看庫函數的資訊,需要在編譯是再加入“-lc_p”編譯參數代替“-lc”編譯參數,這樣程式會連結libc_p.a庫,才可以產生庫函數的profiling資訊。
2) gprof只能在程式正常結束退出之後才能產生程式測評報告,原因是gprof通過在atexit()裡註冊了一個函數來產生結果資訊,任何非正常退出都不會執行atexit()的動作,所以不會產生gmon.out檔案。如果你的程式是一個不會退出的服務程式,那就只有修改代碼來達到目的。如果不想改變程式的運行方式,可以添加一個訊號處理函數解決問題(這樣對代碼修改最少),例如:
static void sighandler( int sig_no )
{
exit(0);
}
signal( SIGUSR1, sighandler );
當使用kill -USR1 pid 後,程式退出,產生gmon.out檔案。
編輯
其他 C/C++ 程式分析器
還有其他很多分析器可以使用gprof 的資料, 例如KProf (截屏) 和 cgprof。雖然圖形介面的看起來更舒服,但我個人認為命令列的gprof 使用更方便。
完