性能工具gperftools使用说明-CPU profiler

gperftools是google开发的一款非常实用的工具集,主要包括:
1.性能优异的malloc free内存分配器tcmalloc;
2.基于tcmalloc的堆内存检测和内存泄漏分析工具heap-profiler,heap-checker;
3.基于tcmalloc实现的程序CPU性能监测工具cpu-profiler.

本文主要讲述profiler在CPU性能分析方面的使用

CPU profiler的使用方式类似heap-profiler,区别就是要在构建你的程序时不仅要链接-ltcmalloc还要链接-lprofiler。它也是需要一个函数调用(ProfilerStart)来开启,和一个函数调用(ProfilerStop)来关闭,调用这些函数需要include 。当然我们还是通过内部的自定义指令机制来运行时控制profiler的开启和关闭。ProfilerStart接受输出文件名作参数,ProfilerStop关闭profiler时同时输出含有profile信息的文件,这些信息也是要pprof解析后可以生成各种可读格式:
% pprof /bin/ls ls.prof
Enters “interactive” mode
% pprof –text /bin/ls ls.prof
Outputs one line per procedure
% pprof –gv /bin/ls ls.prof
Displays annotated call-graph via ‘gv’
% pprof –gv –focus=Mutex /bin/ls ls.prof
Restricts to code paths including a .*Mutex.* entry
% pprof –gv –focus=Mutex –ignore=string /bin/ls ls.prof
Code paths including Mutex but not string
% pprof –list=getdir /bin/ls ls.prof
(Per-line) annotated source listing for getdir()
% pprof –disasm=getdir /bin/ls ls.prof
(Per-PC) annotated disassembly for getdir()
% pprof –text localhost:1234
Outputs one line per procedure for localhost:1234
% pprof –callgrind /bin/ls ls.prof
Outputs the call information in callgrind format
我们实践中用的最多的是导出成pdf格式,非常直观,描述文档在此http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html,
因为这个有向图代表的意义类似之前在heap-profiler中所描述的图,所以不再多着笔墨。
实践证实CPU profiler效果很好,为我们一次次定位了性能热点,为此让人好奇其实现原理。
CPU profiler的原理类似许多其他proflier,都是对运行着的程序定时采样,最后根据每次记录的堆栈频度导出采样信息。
网上有人这样解释到:相当于用gdb attach一个正在运行的进程,然后每隔一段时间中断程序打印堆栈,当然耗时最多的调用最频繁的堆栈是最常被打印出来的。
有稍微看过gperftools这方面的实现,大致就是注册一个定时触发的信号(SIGPROF)处理函数,在此函数中获取当前堆栈信息,通过hash算法以此做hash表的key,放入样本统计hash table中,如果hash table中已经有同样的堆栈key了,value就加1,这样当采样结束,就把hash table的统计信息导出到文件供pprof程序解析,从而得到真正直观的profile信息。

1. 下载 gperftools (wget https://gperftools.googlecode.com/files/gperftools-2.1.tar.gz)
mkdir ../gperftools
./configure prefix=/home/tools/gperftools
make && make install

2. 下载libunwind (wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz)
mkdir ../libunwind
./configure prefix=/home/tools/libunwind
make && make install
3. export LD_LIBRARY_PATH=/home/tools/gperftools/lib
export PATH=$PATH:/home/tools/gperftools/bin

===Archlinux替代1-3:pacman -S gperftools
如果需要生成图表 pacman -S graphviz
如果需要生成打印 pacman -S gv

4. mkdir test && cd test

nano -w test.cpp
#include 
#include 
using namespace std;
void test1() 
{
    int i = 0;
    while (i < 1000) 
     {
        i++;
    } 
}
void test2()
{
    int i = 0;
    while (i < 2000)  
   {
        i++;
    } 
}

void test3() 
 {
    for (int i = 0; i < 100000; ++i)
    {
        test1();
        test2();
    } 
}

int main()
 {
    ProfilerStart("test.prof"); // test.prof is the name of profile file
    test3();
    cout<<"Finish!"<

5. 编译
编译版本:
g++ -o test test.cpp -I /home/tools/gperftools/include -I /home/tools/libunwind/include -L/home/tools/gperftools/lib/ -lprofiler -L/home/tools/libunwind/lib/ -lunwind
安装版本:
g++ -o test test.cpp -lprofiler -lunwind
6. 生成test.prof文件

   [root@nasSrv test]# ./test
   Finish!
   PROFILE: interrupts/evictions/bytes = 133/6/544

7. pprof --text test test.prof
输出:

Using local file test.
Using local file test.prof.
Total: 133 samples
      74  55.6%  55.6%       74  55.6% test2
      59  44.4% 100.0%       59  44.4% test1
       0   0.0% 100.0%      133 100.0% __libc_start_main
       0   0.0% 100.0%      133 100.0% main
       0   0.0% 100.0%      133 100.0% test3

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在C/C++分类目录。将固定链接加入收藏夹。