使用 gperftools 進行性能分析

安裝 gperftools

  • gperftools 下載 release 。
  • 編譯並安裝。
$ ./configure

若產生如下輸出,則需要安裝 libunwind

$ configure: WARNING: No frame pointers and no libunwind. Using experimental backtrace capturing via libgcc. Expect crashy cpu profiler.

查找並安裝 libunwind ,之後再重新 ./configure

$ sudo apt-cache search libunwind
$ sudo apt-get install libunwind-dev
# 重新
$ ./configure

編譯並安裝。

$ make
$ sudo make install

直接安裝 gperftools

不想源碼安裝,也可以直接安裝 package 。

$ apt-cache search libgoogle-perftools-dev
libgoogle-perftools-dev - libraries for CPU and heap analysis, plus an efficient thread-caching malloc

使用 gperftools

#include <algorithm>
#include <random>
#include <string>
#include <vector>

int main()
{
  std::vector<std::string> vec;
  std::mt19937_64 gen(43);

  for (int count = 0; count < 3; ++count)
  {
    for (int i = 0; i < 10 * 1000 * 1000; ++i)
    {
      char buf[64];
      snprintf(buf, sizeof buf, "%016lx", gen());
      vec.push_back(buf);
    }
    std::sort(vec.begin(), vec.end());  // 如果用 tcmalloc 2.5,這行註釋掉反而會變慢!
    vec.clear();
  }
}

下面編譯代碼在一些系統上是不會動態鏈接到 libprofiler.so 的,比如下面就沒有鏈接到。

$ g++ -g -Wall -O0 -std=c++11 test.cc -lprofiler
$ ldd a.out # 未發現 libprofiler.so

換成下面的編譯即可,詳情見 no output is generated after executing the codegperftools - profile file not dumped

$ g++ -g -Wall -O0 -std=c++11 test.cc -Wl,--no-as-needed,-lprofiler,--as-needed
$ ldd a.out
libprofiler.so.0 => not found

編譯鏈接後再 ldd 發現了新問題 not found 。同時運行程序輸出如下:

$ ./a.out
./a.out: error while loading shared libraries: libprofiler.so.0: cannot open shared object file: No such file or directory

由於剛安裝完庫文件,此時更新動態庫 ldconfig 即可。詳情見 Google perftool cannot read file “libprofiler.so.0”

$ sudo ldconfig
$ ldd a.out
libprofiler.so.0 => /usr/local/lib/libprofiler.so.0 (0x00007f8f38050000)

運行程序產生 a.prof 性能文件。

$ env CPUPROFILE=a.prof ./a.out
PROFILE: interrupts/evictions/bytes = 5168/778/195368
  • 使用 LD_PRELOAD 動態添加 profiler 。

像平常一樣正常編譯鏈接。

$ g++ -O a2.out -g -Wall -O0 -std=c++11 test.cc

動態添加。

$ env LD_PRELOAD=libprofiler.so CPUPROFILE=a2.prof ./a2.out
PROFILE: interrupts/evictions/bytes = 5148/740/191200
# 或
$ env LD_PRELOAD=/usr/local/lib/libprofiler.so CPUPROFILE=a3.prof ./a2.out
PROFILE: interrupts/evictions/bytes = 5231/721/190744

使用 pprof 查看性能分析指標

根據 gperftools README 可知 gperftools 中的 pprof 暫時還被保留但已廢棄,需下載新的 pprof

  • 編譯並安裝 pprof 。
$ export GOPATH=/home/ylme/work/download/pprof
$ go get -u github.com/google/pprof
  • 運行 pprof 並且通過瀏覽器查看結果,但瀏覽器卻顯示 Could not execute dot; may need to install graphviz. ,而 pprof 輸出如下。
$ ../download/pprof/bin/pprof -http 0.0.0.0:8080 a.prof
Serving web UI on http://0.0.0.0:8080
Couldn't find a suitable web browser!
Set the BROWSER environment variable to your desired browser.
Failed to execute dot. Is Graphviz installed?
exec: "dot": executable file not found in $PATH
  • 安裝 graphviz 並重新查看結果 http://127.0.0.1:8080
$ sudo apt-get install graphviz

遇見的問題

  • gperftools 文檔見 doc
  • 未安裝 libunwind 庫文件。
  • 運行可執行文件無法產生性能文件。
  • 未鏈接到動態庫 libprofiler.so 。
  • 未安裝 graphviz 而無法用 pprof 查看圖表。

截圖如下:

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