使用 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 查看图表。

截图如下:

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