gprof介紹

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 使用更方便。


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