第一次個人作業【六】(Linux性能分析)
工具選擇
這裏參考了http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-profiling-linux/這個博客,它主要分析了三款Linux平臺下主流的熱點分析工具,分別是GNU gprof、Valgrind和Google perftools,三款工具的主要特點如下表:
工具 | 使用命令 | 是否需要重新編譯 | Profiling速度 | 是否支持多線程熱點分析 | 是否支持鏈接庫熱點分析 |
GNU gprof | ./test; gprof ./test ./gmon.out | 是 | 慢 |
否 | 否 |
Valgrind | Valgrind --tool=callgrind ./test | 否 | 非常慢 | 是 | 是 |
Google perftools | LD_PRELOAD=/usr/lib/libprofiler.so CPUPROFILE=./test.prof ./test | 否 | 快 | 是 | 是 |
gprof
gprof是GNU G++自帶的熱點分析工具,使用方法是:
- 使用 -pg 選項重新編譯代碼;
- 執行你剛才生成的程序,生成熱點分析結果(默認名稱為:gmont.out);
- 使用gprof查看結果。
相關命令:
#!/bin/bash # build the program with profiling support (-gp) g++ -std=c++11 -pg test.cpp -o test # run the program; generates the profiling data file (gmon.out) ./test # print the callgraph gprof test
因為gprof要求用-pg重新編譯代碼,需要在Debug模式下進行Profiling,所以速度較慢。
另外gprof不支持多線程的熱點分析。這個工具另一個大問題是,不支持鏈接庫的熱點分析。
很多大型項目為了模塊化管理會生成很多動態鏈接庫供其他程序調用,如果要分析每個模塊的熱點,這個工具就不適用了。
valgrind/callgrind
valgrind是一系列工具的套裝,包括內存分析、熱點分析等。它的使用非常簡單,安裝好之後,直接調用Vallgrind中的callgrind工具即可,命令為Valgrind --tool=callgrind ./test。使用該工具Profiling無需重新編譯代碼,也支持多線程和鏈接庫的熱點分析,但是由於Profiling原理的特殊性,其Profiling速度非常之慢,比直接運行程序慢了將近50倍,所以並不適合稍大型程序的熱點分析。
使用方法:
- 編譯代碼;
- 利用Vallgrind執行你剛才生成的程序來獲得分析文件:--tool=callgrind;
- 查看分析文件利用例如KCachegrind。
相關命令:
#!/bin/bash # build the program (no special flags are needed) g++ -std=c++11 test.cpp -o test # run the program with callgrind; generates a file callgrind.out.12345 that can be viewed with kcachegrind valgrind --tool=callgrind ./test # open profile.callgrind with kcachegrind kcachegrind profile.callgrind
分析文件展示如圖:
gperftools
gperftools原是Google內部的性能分析工具,後來在Github上開源了,地址是https://github.com/gperftools/gperftools。gperftools 的工作原理為通過定期采樣當前正在執行的指令進行性能分析,如果某個函數被采樣到的次數越多,則該函數在執行時占用的時間比例越大,很可能就是性能瓶頸。 gperftools 可以在被測軟件處於 Release 模式下進行性能分析,所以能最大程度的模擬軟件的實際使用情況。這個工具使用起來也比較簡單。使用該工具Profiling無需重新編譯代碼,也支持多線程和鏈接庫的熱點分析,同時由於其是通過定期采樣正在執行的指令進行熱點分析,所以Profiling速度非常快,和正常release下執行程序的速度幾乎相當。
所以在這裏重點說明一下gperftools的用法。
安裝libunwind
gperftools在64位系統上需要unwind庫的支持,所以需要先安裝libunwind,且官方文檔推薦使用libunwind-0.99版本。
下載地址(註意可能要FQ):http://download.savannah.gnu.org/releases/libunwind/
安裝gperftools
下載地址:https://github.com/gperftools/gperftools
安裝 Graphviz 和 kcachegrind
執行:
sudo apt-get install graphviz sudo apt-get install kcachegrind
怎麽用gperftools
Gernot.Klingler博客上是這樣寫的:
Creating a CPU profile of selected parts of your application with gperftools requires the following steps:
- compile your program with debugging symbols enabled (to get a meaningful call graph) and link gperftools profiler.so
#include <gperftools/profiler.h>
and surround the sections you want to profile withProfilerStart("nameOfProfile.log");
andProfilerStop();
- execute your program to generate the profiling data file(s)
- To analyze the profiling data, use pprof (distributed with gperftools) or convert it to a callgrind compatible format and analyze it with KCachegrind
命令:
#!/bin/bash # build the program; For our demo program, we specify -DWITHGPERFTOOLS to enable the gperftools specific #ifdefs g++ -std=c++11 -DWITHGPERFTOOLS -lprofiler -g ../cpuload.cpp -o cpuload # run the program; generates the profiling data file (profile.log in our example) ./cpuload # convert profile.log to callgrind compatible format pprof --callgrind ./cpuload profile.log > profile.callgrind # open profile.callgrind with kcachegrind kcachegrind profile.callgrind
性能分析
在這裏我還是用了valgrind,因為想安裝gperftools的時候被墻了,同時valgrind安裝也比gperftools簡單的多。
從圖中可以看出OneFileCount()函數仍然占據了大部分的時間,而該函數中又以MAP的相關操作占大頭,與WINDOWS下基本一致,根據這個情況可以提出下一步的優化目標,例如自己寫HASH表等。
第一次個人作業【六】(Linux性能分析)