天天看點

(zz)使用gprof和oprofile工具分析系統性能

有些時候,我們特别關注程式的性能,特别是底層軟體,比如驅動程式,OS等。為了更好的優化程式性能,我們必須找到性能瓶頸點,“好鋼用在刀刃上”才能取 得好的效果,否則可能白做工作。為了找到關鍵路徑,我們可以使用profilng技術,在linux平台上,我們可以使用gprof和oprofile工 具。

  • gprof是GNU工具之一,它在編譯的時候在每個函數的出入口加入了profiling的代碼,運作時統計程式在使用者态的 執行資訊,可以得到每個函數的調用次數,執行時間,調用關系等資訊,簡單易懂。适合于查找使用者級程式的性能瓶頸,對于很多時間都在核心态執行的程 序,gprof不适合。
  • oprofile也是一個開源的profiling工具,它使用硬體調試寄存器來統計資訊,進 行profiling的開銷比較小,而且可以對核心進行profiling。它統計的資訊非常的多,可以得到cache的缺失率,memory的訪存信 息,分支預測錯誤率等等,這些資訊gprof是得不到的,但是對于函數調用次數,它是不能夠得到的。。

簡單來說,gprof簡單,适合于查找使用者級程式的瓶頸,而oprofile稍顯複雜,但是得到的資訊更多,更适合調試系統軟體。

我們以編譯運作hello.c為例,來說明如何使用這兩個工具,這裡不解釋具體結果的含義,要想詳細了解每個結果代表什麼意思,可以看一下參考資料中官方 站點上的doc資訊,裡面會給你詳盡的解釋。

Gprof 實作原理:

通過在編譯和連結你的程式的時候(使用 -pg 編譯和連結選項),gcc 在你應用程式的每個函數中都加入了一個名為mcount ( or “_mcount” , or “__mcount” , 依賴于編譯器或作業系統)的函數,也就是說你的應用程式裡的每一個函數都會調用mcount, 而mcount 會在記憶體中儲存一張函數調用圖,并通過函數調用堆棧的形式查找子函數和父函數的位址。這張調用圖也儲存了所有與函數相關的調用時間、調用次數等等的所有資訊,另外,如果想檢視庫函數的profiling,需要在編譯是再加入“-lc_p”編譯參數代替“-lc”編譯參數,這樣程式會連結libc_p.a庫,才可以産生庫函數的profiling資訊。如果想執行一行一行的profiling,還需要加入“-g”編譯參數。

gprof Quick Start

gprof是gnu binutils工具之一,預設情況下linux系統當中都帶有這個工具。

  1. 使用 -pg 選項來編譯hello.c,如果要得到帶注釋的源碼清單,則需要增加 -g 選項。運作: gcc -pg -g -o hello hello.c
  2. 運作應用程式: ./hello 會在目前目錄下産生gmon.out檔案
  3. 使用gprof來分析 gmon.out檔案,需要把它和産生它的應用程式關聯起來:
    1. gprof hello gmon.out -p 得到每個函數占用的執行時間
    2. gprof hello gmon.out -q 得到call graph,包含了每個函數的調用關系,調用次數,執行時間等資訊。
    3. gprof hello gmon.out -A 得到一個帶注釋的“源代碼清單”,它會注釋源碼,指出每個函數的執行次數。這需要在編譯的時候增加 -g選項。

oprofile Quick Start

oprofile是sourceforge上面的一個開源項目,在2.6核心上帶有這個工具,好像隻有smp系統才有。比較老的系統,需要自己安裝,重新 編譯核心。

    oprofile是一套工具,分别完成不同的事情。

op_help: 列出所有支援的事件。

opcontrol:設定需要收集的 事件。

opreport: 對結果進行統計輸出。

opannaotate:産生帶注釋的源/彙編檔案,源語言級的注釋需要編譯源檔案時的 支援。

opstack:    産生調用圖profile,但要求x86/2.6的平台,并且linux2.6安裝了call-graph patch

opgprof:    産生如gprof相似的結果。

oparchive: 将所有的原始資料檔案收集打包,可以到另一台機器上進行分析。

op_import: 将采樣的資料庫檔案從另一種abi轉化成本地格式。     運作oprofile需要root權限,因為它要加載profile子產品,啟動oprofiled背景程式等。是以在運作之前,就需要切換到root。

  1. opcontrol --init 加載子產品,mout /dev/oprofile 建立必需的檔案和目錄
  2. opcontrol --no-vmlinux 或者 opcontrol --vmlinux=/boot/vmlinux-`uname -r` 決定是否對kernel進行profiling
  3. opcontrol --reset 清楚目前會話中的資料
  4. opcontrol --start 開始profiling
  5. ./hello 運作應用程式,oprofile會對它進行profiling
  6. opcontrol --dump 把收集到的資料寫入檔案
  7. opcontrol --stop 停止profiling
  8. opcotrol -h 關閉守護程序oprofiled
  9. opcontrol --shutdown 停止oprofiled
  10. opcontrol --deinit 解除安裝子產品

常用的是3→7這幾個過程,得到性能資料之後,可以使用 opreport, opstack, opgprof, opannotate幾個工具進行分析,我常用的是opreport, opannotate進行分析。

  1. opreport使用 http://oprofile.sourceforge.net/doc/opreport.html
  2. opannotate使用 http://oprofile.sourceforge.net/doc/opannotate.html
  3. opgprof使用 http://oprofile.sourceforge.net/doc/opgprof.html

最常用的是 opreport,這個可以給出image和symbols的資訊,比如我想得到每個函數的執行時間占用比例等資訊,用來發現系統性能瓶頸。 opannotate可以對源碼進行注釋,指出哪個地方占用時間比較多。常用指令如下:

  • opreport -l /bin/bash --exclude-depand --threshold 1 , 用來發現系統瓶頸。
  • opannotate --source --output-dir=annotated /usr/local/oprofile-pp/bin/oprofiled
  • opannotate --source --base-dirs=/tmp/build/libfoo/ --search-dirs=/home/user/libfoo/ --output-dir=annotated/ /lib/libfoo.so

網絡資源

  1. gprof 使用者手冊 http://sourceware.org/binutils/docs-2.17/gprof/index.html
  2. oprofile官方站點 http://oprofile.sourceforge.net/
  3. 使用 GNU profiler 來提高代碼運作速度 http://www-128.ibm.com/developerworks/cn/linux/l-gnuprof.html
  4. 使用 OProfile for Linux on POWER 識别性能瓶頸 http://www-128.ibm.com/developerworks/cn/linux/l-pow-oprofile/

繼續閱讀