google-perf-tools 试用
最近项目中需要进行性能优化,用到了googleperftools,它可以对cpu的使用率进行统计,这里简要记录一下用法。
一、下载地址 http://code.google.com/p/google-perftools/
二、编译. x86_64体系结构上,需要首先安装libunwind,下载地址: http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz
然后正常步骤安装即可
三、编写简单测试程序 testperf.cpp
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int b() 5 { 6 int count = 500000000; 7 int i = 0; 8 for(i = 0;i < count ; ++i) 9 { 10 } 11 return 0; 12 } 13 int a() 14 { 15 int count = 1000000000; 16 int i = 0 ; 17 for(i = 0; i < count ;++i) 18 { 19 } 20 b(); 21 return 0; 22 } 23 24 int main() 25 { 26 a(); 27 return 0; 28 }
此函数就是主函数中调用a函数,a函数首先循环10亿次,然后调用b函数,b函数循环5亿次。
四、 编译:g++ testperf.cpp -lprofiler -o testperf
此处需要链接libprofiler.so进行编译
五、设置环境变量并且执行程序:env CPUPROFILE=/home/wudi/test/testperf.prof /home/wudi/test/testperf
含义:testperf 这个可执行程序执行后生成的供pprof分析的统计信息写到CPUPROFILE 这个环境变量中,执行这步后,会
生成/home/wudi/test/testperf.prof 这个文件。
六、利用pprof来解析这个prof文件并且输出图表或者文本。
pprof --gif ./testperf testperf.prof > prof.gif
这里会将分析的结果以gif文件进行输出到prof.gif文件中,还有很多输出选项,比如--pdf 用于输出到pdf文件,--gv 用于生成postscript脚本,供gv程序进行显示,需要预先安装
gv和dot
这个程序生成的gif图如下:
这个图显示了函数间的调用关系,还显示了整个程序执行期间各个函数所消耗的cpu百分比,下面进行解释。
Total samples : 443 表明对程序进行了cpu使用率采样,一共进行了443次,默认情况下,每秒采样100次(可以用环境变量CPUPROFILE_FREQUENCY来控制,默认100),
那么相当于说,每采样一次间隔10ms,这里程序采样了443次,可以说明,程序大约执行了4.43s.
每个结点代表一个函数,从上往下依次显示:函数所在类名,函数名,函数所消耗cpu的百分比(不包括其调用的函数), 函数所消耗的cpu的百分比(包括其调用的函数)
在这里由于测试程序没有类,所以类名没有显示。这幅图表明,函数a自身消耗了66.6%的cpu,执行了2.95s , 均不包括其调用的函数b,函数b自身消耗了百分之33.4%的cpu,执行了1.48s, 函数a自身加上其调用的函数b一共消耗100%的cpu, 执行了4.43s
结点a和结点b之间的边上的数值148表示函数a调用函数b,函数b总共执行了1.48s。用下面这个更复杂的图来说明:
图最下方 vsnprintf()函数调用了下面四个函数,边上的数值分别是3,2,2,5,四个数值加起来等于12,刚好等于vsnprintf节点的18-6
如果编译的时候加上-O2 优化,可能会发现生成的调用关系图和实际代码路径有点差别,这是由于图基于优化后代码运行时采样生成的。
另外,如果程序函数较多,而是想关注某个函数的调用关系,可以加上--focus 参数,比如,如果只想关注和vsnprintf有关系的调用关系,可以加上--focus=vsnprintf,这样生成的图会简单很多。同样,如果不想关注某个函数,可以加上--ignore参数,比如--ignore=vsnprintf
参考资料:
http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html