支持HW团队,就支付宝领取下面的红包吧!(2018年3月31前,就几毛,也会几块,可以和其他红包叠加使用),你领取消费,HW有奖励。红包使用无条件限制,有条件请注意是不是有病毒。

小伙伴们,给大家发红包喽!人人可领,领完就能用。祝大家领取的红包金额大大大!#吱口令#长按复制此消息,打开支付宝就能领取!er1OEj73Uj

登入 注册 | 验证
| 搜索
HelloWorld论坛 : > 计算机科学、技术、教学> 编程专题> 开源免费项目> [转] 性能优化利器---gprof使用案例介绍
 
 
 
 
 
 
类别:c++ 阅读:5732 评论:0 时间:十月 16, 2013, 7:35 p.m. 关键字:

 

 来源:http://home.hundsun.com/Forum.aspx/t-13251

 

GNU gprof 是一款Linux平台上的程序分析软件。借助gprof可以获得C程序运行期间的统计数据,例如每个函数耗费的时间,函数被调用的次数以及各个函数相互之间的调用关系。gprof可以帮助我们找到程序运行的瓶颈,对占据大量CPU时间的函数进行调优(gprof统计的只是CPU的占用时间,对I/O瓶颈貌似无能为力,耗时甚久的I/O操作很可能只占据极少的CPU时间)。

gprof的使用非常简单,在编译链接的时候加上"-pg"选项,然后按照正常方式运行程序,如果程序正常退出,一个名为gmon.out将会产生。使用gprof可查看gmon.out中的统计结果。

gprof的基本原理:

类似于gdbgprof需要对待分析的程序做一些改动,因此在程序编译的时候需要加上"-pg"选项,如果程序的某个模块在编译的时候没有加上"-pg",则该模块的函数会被排除在统计范围之外,即:如果你想将libxxx.a中的函数也纳入统计跟踪范围,则该库需要加上-pg编译参数并重新编译成一个测试版libxxx.a

 

利用gprof优化代码的案例:

libmxml是一个开源的XML解析库,在做新产品预研时,想验证一下其处理性能,与我们正在使用的libsxml进行比较,编写了一个综合的测试用例后,发现其处理性能不理想,但由于其代码量比较大,在综合测试用例的场景下,不清楚哪些函数是其处理瓶颈,是否有优化的空间,遂祭出gprof这把“手术刀”,解剖一下其内部每个函数的执行情况,看看到底慢在哪?

实现过程:

1)       libmxml.a,加上-pg编译参数,重新编译;

2)       mxml_bench专用的测试案例程序,加-pg参数,重新编译;

3)       运行gprof mxm_bench让其带HACK运行并显示出运行结果报告;

4)       对结束报告进行分析,观察哪些函数调用最频繁,耗时最多,对调用频繁而耗时多的函数,分析其代码看哪些可以优化。

 优化前运行测试案例:

 

 gprof 输出字段含义说明:

Gprof 产生的信息解释:

%time

Cumulative

seconds

Self

Seconds

Calls

Self

TS/call

Total

TS/call

name

函数消耗时间占程序所有时间百分比

函数累计执行的时间

(单位秒)

该函数本身执行时间

函数被调用次数

调用一次函数平均执行时间

(不包括调用函数)

调用一次函数的平均时间(包括调用的函数)

函数名

由上图可看出,该程序运行过程中,频率最高的三个函数为mxmlLocalPath()mxmlLocalNode ()xml_GetElement(),只要这三个函数其中之一进行优化,应该能取得一定的效果!

         通过以上三个函数代码分析,进行适当的代码精简、优化,反复几次测试,找到了原因,其中的mxmlLocalNode()函数中:

1、  strcpy改为memcpy,能小幅提升性能;

2、    优化使用频率最高的mxmlLocalNode()函数,在找不到时

即:mxml_error内部使用了vsnprintf()这个变函数,虽然功能较强大,但它是一个低效的操作,不能放在高效的处理过程中!

        

经过以上处理过程优化后,再运行mxml_bench程序,得到结果:

 

从结果上,TPS(每秒处理综合XML操作数)2833提升到4181,提升了约50%的性能!

性能提升的主要原因:mxmlLocalNode()的处理性能有一定程度的提高,其中的self seconds(函数本身执行时间)从15.11降到14.10,下降了6.7%,但由于该函数是使用频率最高的那个函数,所以该函数性能提升后,将让出更多的CPU资源给其它函数使用,对整体的性能提升非常明显;

         通过gprof得到每个函数的运行情况后,进行相应代码优化的策略建议:

1、  循环次数很多的循环体内部,这个优化是收益最高的一种优化之一,循环体内部约N条指令,最终收益将乘以循环次数,常见的如将循环体内不变的变量移动到循环体外,多重循环嵌套的顺序问题;

2、  在高频访问的函数中,查找/定位是否有低效的函数调用,如sprintf()/log等,此类优化能明显提升整体处理性能;

3、  优化函数调用:这是优化提高非常明显的一种方式,常见的方式如函数申明为inline、避免在高频函数中使用递归调用等,这样可以节约大量的函数调用开销,避免多次的压栈出栈;

4、  优化内存寻址,避免重复的内存寻址;

5、  优化CPU流水线的分支预测的成功率,如if  ~  else if  ~  else 语句,将满足条件概率最高放在靠前的位置;

 

 

 

 

[挂载人]初学MPEG [审核人]初学MPEG 推荐

个人签名--------------------------------------------------------------------------------

Please Login (or Sign Up) to leave a comment