http://blog.csdn.net/fenghaibo00/article/details/9007263
對於做應用層級(相對核心開發)的開發,如果只想快速找到代碼效能瓶頸而對OProfile的工作原理不感興趣,只看該樣本應該就足夠了。
假如我們的代碼檔案是/home/leo/oprofile_test/main.cpp,內容是:
[cpp] view plain copy #include <stdio.h> #include <unistd.h> #include <string.h> class FileOp { public: FileOp(char *file) { strcpy(m_fileName, file); m_buff = new char[1024]; memset(m_buff, 0, 1024); } ~FileOp() { delete []m_buff; m_buff = NULL; } void DoWork() { FILE *fp = fopen(m_fileName, "r"); if(!fp) { return; } int count = 0; int i = 0; while(!feof(fp)) { fgets(m_buff, 1023, fp); count = strlen(m_buff); usleep(100); fprintf(stderr, "The %ld has %ld characters!\n", ++i, count); } fclose(fp); } private: char m_fileName[1024]; char *m_buff; }; int main(int argc, char **argv) { if(argc != 2) { return -1; } FileOp op(argv[1]); op.DoWork(); return 0; }
這段程式讀取一個從命令列傳遞過來的一個檔案,列印出每一行的字元數(這段代碼是在64位機器上啟動並執行)。
a) 使用“g++ -g main.cpp”將原始碼編譯成可執行程式
b) 使用“opcontrol --init”進行分析器初始化(啟動分析器驅動模組)
c) 使用“opcontrol --setup --image=/home/leo/oprofile_test/a.out --event=CPU_CLK_UNHALTED:6000:0”和“opcontrol --no-vmlinux”設定分析器,如下圖所示:
d) 使用“opcontrol --start”啟動分析器
e) 運行程式,比如:“./a.out /var/log/messages.1”
運行完成後,使用下面的命令擷取分析結果。
a) 運行“opcontrol --dump”將採樣資料送入分析器中
b) 運行“opreport -l”查看函數級的分析結果,如下圖所示:
由圖中可以看到FileOp::DoWork的採樣百分比佔到了99.0909%,說明大部分的CPU時間都是在此函數中。
c) 運行“opannotate --source”查看代碼層級的分析結果,如下圖所示:
上圖只是截取了關鍵的部分輸出,從這個輸出可以看到strlen這行佔到了77%(紅色矩形中數字768表示在分析採樣過程中改行採樣數量為768,即每次設定的事件發生時查看運行所在的代碼位置,發現一次就對改行的採樣數加1,。77.5758代表改行採樣數占所有採樣數的77.5758%),說明這段代碼的運行效率很低,找到了效能瓶頸,接下來的工作就是找函數替換strlen啦。(strlen的效率實在很低,尤其是當字串很長的時候)
OK,到此分析結果已經出來了,不過對於工程很大的情況,opreport和opannotate的輸出很多,這時候把分析結果匯出到檔案中就比較容易查看了,對於opreport,可以使用“opreport -l -o ./analysis.log”來講分析結果輸出到檔案中,如下圖所示:
而對於opannotate來講,可以使用“opannotate --source --output-dir=/tmp/”來講分析結果對應到相應的原始碼檔案中,如下圖所示:
上面的命令的意思是將相應的打了標註的原始碼檔案放在“/tmp/”目錄下,在該目錄下,會根據原始碼的檔案結構產生相對應的檔案結果,如圖,在“/tmp/”目錄下產生了“home/leo/oprofile_test”目錄,與原始碼的目錄一致,而“main.cpp”就在該目錄下,開啟該目錄下的“main.cpp”就可以查看每句代碼對應的採樣資料以及資源佔用百分比了。
用完了分析器,使用命令“opcontrol --stop”停止採樣,命令“opcontrol --reset”清除當前會話中的採樣資料,命令“opcontrol --shutdown”關閉分析器核心模組,“opcontrol --stop” 和命令“opcontrol --reset”是非常有必要的,因為不進行這兩步下次在進行分析時就會受到這次結果的影響。