使用gprof来对程序的性能分析总结

gprof是一款用于分析函数调用耗时的工具,它可以帮助定位程序中最耗时的部分。在使用gprof时,需在gcc链接时添加-pg参数以生成gmon.out文件。然而,gprof默认不支持多线程和共享库程序,且在某些情况下可能无法正确生成输出。解决多进程问题可以设置GMON_OUT_PREFIX环境变量,多线程则需要通过自定义包装pthread_create并使用动态库加载。值得注意的是,gprof对于短时间内执行的函数可能无法准确统计时间。
摘要由CSDN通过智能技术生成

综述

  • gprof用于分析函数调用耗时,可用之抓出最耗时的函数,以便优化程序。
  • gcc链接时也一定要加-pg参数,以使程序运行结束后生成gmon.out文件,供gprof分析。
  • gprof默认不支持多线程程序,默认不支持共享库程序。
  1. gcc -pg 编译程序
  2. 运行程序,程序退出时生成 gmon.out
  3. gprof ./prog gmon.out -b 查看输出

注意事项

  • 程序如果不是从main return或exit()退出,则可能不生成gmon.out。
  • 程序如果崩溃,可能不生成gmon.out。
  • 测试发现在虚拟机上运行,可能不生成gmon.out。
  • 一定不能捕获、忽略SIGPROF信号。man手册对SIGPROF的解释是:profiling timer expired. 如果忽略这个信号,gprof的输出则是:Each sample counts as 0.01 seconds. no time accumulated.
  • 如果程序运行时间非常短,则gprof可能无效。因为受到启动、初始化、退出等函数运行时间的影响。
  • 程序忽略SIGPROF信号!

原理

gcc -pg 在应用程序的每个函数中添加了名为 mcount/mcount/_mcount的函数。 应用程序每个函数执行时都会执行mcount,而mcount则会在内存中保存一张函数调用图, 通过函数调用堆栈的形式,查找子函数、父函数的地址,也保存了与函数相关的调用时间、次数等信息。

多进程

如果用gprof分析多进程程序,则可能一个进程的gmon.out覆盖另一个进程的gmon.out, 解决方法是在执行程序之前执行:export GMON_OUT_PREFIX=x.out 则之后生成的文件名就如x.out.pid,多进程的gmon.out就不会相互覆盖。

多线程

gprof无法分析多线程程序。缘故是gprof使用ITIMER_PROF定时器, 当超时时由内核向应用程序发送信号。但多线程程序只有主线程接收ITIMER_PROF。 这里有一个简单的实现方法: 对pthread_create进行包装,并以动态库的形式在程序运行前加载。 我通过上文的描述,整理了一个gprof分析多线程程序的程序,可供参考。

<span class="pln" style="color: rgb(0, 0, 0);">$ gcc </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">shared </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">fPIC gprof_helper</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">c </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">o ghelper2</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">so </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">lpthread </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">ldl  </span><span class="com" style="color: rgb(136, 0, 0);"># create ghelp2.so</span><span class="pln" style="color: rgb(0, 0, 0);">
$ gcc test</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">c </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);">lpthread
$ </span><span class="pun" style="color: rgb(102, 102, 0);">./</span><span class="pln" style="color: rgb(0, 0, 0);">a</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="kwd" style="color: rgb(0, 0, 136);">out</span><span class="pln" style="color: rgb(0, 0, 0);"> 
    hello gprof     </span><span class="com" style="color: rgb(136, 0, 0);"># output</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值