您的位置:首页 > 编程语言 > Go语言

使用 google-perftools 剖析程序性能瓶颈

2014-03-04 16:13 405 查看

使用google-perftools剖析程序性能瓶颈

冯文龙,软件工程师,IBM

冯文龙,IBMWPLCLotus软件开发工程师。主要从事Linux客户端软件的开发,对Gtk相关的桌面技术有一定的研究。

简介:google-perftools是一款优秀的LinuxC/C++程序的性能剖析及优化工具,它提供了将目标程序运行时所消耗的CPU时间片进行剖析和图形化输出剖析结果的功能。本文将从零开始,一步一步引导读者搭建并运行一个google-perftools的剖析环境,并用一个示例来演示如何使用该工具找到目标程序的性能瓶颈。

发布日期:2010年12月16日

google-perftools简介

google-perftools是一款针对C/C++程序的性能分析工具,它是一个遵守BSD协议的开源项目。使用该工具可以对CPU时间片、内存等系统资源的分配和使用进行分析,本文将重点介绍如何进行CPU时间片的剖析。google-perftools对一个程序的CPU性能剖析包括以下几个步骤。

1.编译目标程序,加入对google-perftools库的依赖。

2.运行目标程序,并用某种方式启动/终止剖析函数并产生剖析结果。

3.运行剖结果转换工具,将不可读的结果数据转化成某种格式的文档(例如pdf,txt,gv等)。

安装

您可以在google-perftools的网站(http://code.google.com/p/google-perftools/downloads/list)上下载最新版的安装包。为完成步骤3的工作,您还需要一个将剖析结果转化为程序员可读文档的工具,例如gv(http://www.gnu.org/software/gv/)。

编译与运行

您需要在原有的编译选项中加入对libprofiler.so的引用,这样在目标程序运行时会加载工具的动态库。例如本例中作者的系统中,libprofiler.so安装在"/usr/lib"目录下,所以需要在makefile文件中的编译选项加入“-L/usr/lib-lprofiler”。

google-perftools需要在目标代码的开始和结尾点分别调用剖析模块的启动和终止函数,这样在目标程序运行时就可以对这段时间内程序实际占用的CPU时间片进行统计和分析。工具的启动和终止可以采用以下两种方式。

a.使用调试工具gdb在程序中手动运行性能工具的启动/终止函数。

gdb是Linux上广泛使用的调试工具,它提供了强大的命令行功能,使我们可以在程序运行时插入断点并在断点处执行其他函数。具体的文档请参照http://www.gnu.org/software/gdb/,本文中将只对用到的几个基本功能进行简单介绍。使用以下几个功能就可以满足我们性能调试的基本需求,具体使用请参见下文示例。

命令
功能
ctrl+c

暂停程序的运行

c

继续程序的运行

b

添加函数断点(参数可以是源代码中的行号或者一个函数名)

p

打印某个量的值或者执行一个函数调用

b.在目标代码中直接加入性能工具函数的调用,该方法就是在程序代码中直接加入调试函数的调用。

两种方式都需要对目标程序重新编译,加入对性能工具的库依赖。对于前者,他的好处是使用比较灵活,但工具的启动和终止依赖于程序员的手动操作,常常需要一些暂停函数(比如休眠sleep)的支持才能达到控制程序的目的,因此精度可能受到影响。对于后者,它需要对目标代码的进行修改,需要处理函数声明等问题,但得到的结果精度较高,缺点是每次重新设置启动点都需要重新编译,灵活度不高,读者可以根据自己的实际需求采用有效的方式。

示例详解

该程序是一个简单的例子,文中有两处耗时的无用操作,并且二者间有一定的调用关系。

清单1.示例程序


voidconsumeSomeCPUTime1(intinput){

inti=0;

input++;

while(i++<10000){

i--;i++;i--;i++;

}

};


voidconsumeSomeCPUTime2(intinput){

input++;

consumeSomeCPUTime1(input);

inti=0;

while(i++<10000){

i--;i++;i--;i++;

}

};


intstupidComputing(inta,intb){

inti=0;

while(i++<10000){

consumeSomeCPUTime1(i);

}

intj=0;

while(j++<5000){

consumeSomeCPUTime2(j);

}

returna+b;

};


intsmartComputing(inta,intb){

returna+b;

};


voidmain(){

inti=0;

printf("reachedthestartpointofperformancebottleneck\n");

sleep(5);

//ProfilerStart("CPUProfile");

while(i++<10){

printf("Stupidcomputingreturn:%d\n",stupidComputing(i,i+1));

printf("Smartcomputingreturn%d\n",smartComputing(i+1,i+2));

}

printf("shouldteminateprofilingnow.\n");

sleep(5);

//ProfilerStop();

}


源代码中粗体的内容(方法1)和斜体的内容(方法2)分别代表了上文中提及胡两种执行剖析的方式。采用方法二时将直接产生结果,采用方法1时需要配合GDB的命令来实现剖析的执行和结束,可用的方法有两种,一种是在程序运行时手动暂停函数的执行,另一种是预设断点,并在断点处执行剖析函数,两种方法(方法a,方法b)在命令行中的具体操作如下。

方法a

gdbYOUR_PROGRAM//启动gdb并选择你的程序为gdb的启动目标

(gdb)r//运行

//等待你需要的条件满足,此处示例中打印了字符

(gdb)Ctrl+c//暂停当前函数

(gdb)pProfilerStart("MyProfile")

(gdb)c//继续程序运行

//等待程序打印目标模块结束,此处示例打印了提示

(gdb)Ctrl+c//暂停当前函数

(gdb)pProfilerStop()

方法b

gdbYOUR_PROGRAM//启动gdb并选择你的程序为gdb的启动目标

(gdb)bmain1.c:47//对应于耗时模块的起始点

(gdb)bmain1.c:52//对应于耗时模块的终止点

(gdb)r//运行

(gdb)pProfilerStart("MyProfile")

(gdb)c//继续程序运行

(gdb)pProfilerStop()

结果分析

程序执行完毕会在程序的当前工作目录下产生名为MyProfile的结果文件。我们可以用以下命令产生可视化的结果文档。

pprof--gv./codeTestMyProfile

其中codeTest对应于用于测试的目标程序文件名,如果您安装了pdf相关的软件您还可以尝试生成pdf格式的结果文档,其对应的命令为

pprof--pdf./codeTestMyProfile>MyProfile.pdf

转换后产生的结果文档如下图。图中的数字和框体的大小代表了的某个函数的运行时间占整个剖析时间的比例。由代码的逻辑可知,stupidComputing,stupidComputing2都是费时操作并且它们和consumeSomeCPUTime存在着一定的调用关系。

图1.剖析结果

结束语

本文介绍了一个Linux平台上的性能剖析工具google-perftools,并结合实例向读者展示了如何使用该工具配置、使用及分析性能瓶颈。

下载

描述
名字
大小
下载方法
本文用到的示例

src.rar

4KB

HTTP

关于下载方法的信息

参考资料

学习

google-perftools主页

developerWorksLinux专区寻找为Linux开发人员(包括
Linux新手入门)准备的更多参考资料,查阅我们

最受欢迎的文章和教程。
在developerWorks上查阅所有
Linux技巧和
Linux教程。
随时关注developerWorks
技术活动和网络广播。

讨论

参与论坛讨论。

欢迎加入
MydeveloperWorks中文社区。

关于作者

冯文龙,IBMWPLCLotus软件开发工程师。主要从事Linux客户端软件的开发,对Gtk相关的桌面技术有一定的研究。

建议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: