原文:http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html
使用分为三步:链接profiler库, 运行代码,分析输出
1,链接profiler库
tcmalloc 的安装略过。使用时通过 -lprofiler 链接profiler库。 或者使用全局变量 (不推荐)
% env LD_PRELOAD="/usr/lib/libprofiler.so" 这一步并没有激活cpu 剖析,只是插入代码而已。所以,总是在开发时总是链接lprofiler到你的可执行程序。
2, 运行代码
这里有两种方法给一个可执行程序激活cpu 剖析:
1, 分析整个程序。定义全局变量CPUPROFILE,用来命名转储的分析结果文件。例如:
% env CPUPROFILE=/tmp/mybin.prof /usr/local/bin/my_binary_compiled_with_libprofiler_so2, 分析特定代码。用
ProfilerStart()
和 ProfilerStop() 把你要分析的代码包起来(头文件<google/profiler.h>)。ProfilerStart()以转储分析结果文件名字作为参数。
在Linux
2.6及以上版本,profiler 在多线程环境下正确工作,它自动的剖析所有线程。在linux 2.4版本,它剖析主线程。 多子进程下也能很好工作。
在头文件google/profiler.h中有些高级使用的函数,包括ProfilerFlush()
和 ProfilerStartWithOptions().
通过定义全局变量可以
定制工具运行时行为,包括CPUPROFILE, CPUPROFILE_REALTIME.
3, 分析输出
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分析文本输出:
文本模式下,输出中的一行类似
14 2.1% 17.2% 58 8.7% std::_Rb_tree::find解释如下:
1. 当前函数性能分析抽样的数量
2,当前函数性能分析抽样所占的比例
3,目前为止所有打印函数性能分析抽样所占的比例
4,当前函数以及它调用的其他函数性能分析抽样的数量
5,当前函数以及它调用的其他函数性能分析抽样所占的比例
6,当前函数的名字
分析Callgrind 输出 : 略
节点信息:
在pprof众多的图形化输出中,输出是带着时序信息的调用图,例如
每个节点表示一个程序,箭头表示调用关系,每个节点如下格式:
Class Name (类名) Method Name (函数名) local (percentage) (当前函数所占比例) of cumulative (percentage)(累计比例)
最后一行或者两行包含时长信息。(性能分析通过一个特别简单的方法:我们默认在一秒钟抽样一百次。所以输出中的时间单位相当于10微妙的执行时间。)“Local”时间是指当前程序直接执行代码指令所花费的时间,不包含他调用的其他程序所花费的时间。“cumulative”时间是指“local”时间和它调用的其他程序所花费时间的总和。如果“local” 时间和“conmulative”时间相等,则不会打印“conmulative” 时间。
例如,test_main_thread()的时长信息显示执行本地代码花费了155个时间单位(大约1.55秒),并且加上它调用的其他的程序比如snprintf()一起花费的时间大约200个时间单位。
节点大小与local 时间成正比例关系。节点中的展示的比例等于抽样次数除以整个程序所有运行时间(也就是main函数的cumulative 抽样次数)
有向边信息
一个节点到另一个节点的有向边表明一个调用者与一个被调用者的关系。有向边上的标签表明了被调用者花费的时间。例如,test_main_thread() 到 snprintf() 的有向边表明test_main_thread()累计花费了200个抽象次数中snprintf()占据了37个。
注意一点, test_main_thread()有到vsnprintf()的有向边,虽然test_main_thread()没有直接调用它。这是因为编译的时候带有优化选项-O2, 性能分析能够反映出优化后的控制流。
元信息
展示的结果顶部应该包含一些元信息,类似
/tmp/profiler2_unittest Total samples: 202 Focusing on: 202 Dropped nodes with <= 1 abs(samples) Dropped edges with <= 0 samples这部分包含了程序名称,性能分析期间总的抽样次数,如果带有选项--focus,该图例中也应该包含重点分析的抽样次数。而且一些不重点的节点和有向边会丢弃减少干扰。关于丢弃的节点和有向边信息也会显示在该图例中
聚焦和忽略
你可以让pprof聚焦或者忽略部分代码 来产生一个结果。你可以指定一个正则表达式。这个调用图的任何一部分所在路径上都至少有一个节点匹配你的正则表达式。其他的调用图被丢弃了。例如,你可以在程序profiler2_unittest中聚焦在vsnpritf()代码库调用,如下所示:
% pprof --gv --focus=vsnprintf /tmp/profiler2_unittest test.prof
类似的,你也可以指点--ignore选择来忽略匹配指定正则表达式的样例。比如除了snprintf, 你对其他所有东西都感兴趣,你可以这样写
% pprof --gv --ignore=snprintf /tmp/profiler2_unittest test.prof
交互模式
默认情况下,如果你不指定任何的选项,pprof就会运行在交互模式下。在提示符下,你可以输入很多上面所提到的命令。通过输入help,你可以获取当前交互模式下提供的所有命令。