根据网上信息整理所成。算法
功能与优劣
gprof实际上只是一个用于读取profile结果文件的工具。gprof采用混合方法来收集程序的统计信息,它使用检测方法,在编译过程当中在函数入口处插入计数器用于收集每一个函数的被调用状况和被调用次数;也使用采样方法,在运行时按必定间隔去检查程序计数器并在分析时找出程序计数器对应的函数来统计函数占用的时间。须要注意的是,gprof统计的只是CPU的占用时间,对I/O瓶颈貌似无能为力,耗时甚久的I/O操做极可能只占据极少的CPU时间。bash
使用
正常运行编译好的程序,程序正常结束后会在当前目录生成统计信息文件gmon.out,也就是说,程序必须正常退出(调用exit或从main中返回)才能生成统计信息。 当前目录下若是有另外叫gmon.out的文件,内容将被本次运行生成的统计信息覆盖,屡次运行统计程序前须要将前几回的gmon.out更名。多线程
$ g++ main.cpp -pg -o main $ ./main # 会生成gmon.out性能分析文件 $ gprof -b main gmon.out > report.txt
这是基本使用方法,更加详细的参见info gprof
。最终呈现的统计信息包括两张表:flat table和call graph。flat table列出了各个函数的运行时间(不包括子函数)及所占总运行时间的比率,函数的调用次数;call graph还包括函数之间的调用关系,详细列出了每一个函数在它的各个子函数上所耗费的时间。函数
生成的信息与解释
Flat Profile的数据解释:工具
%time | Cumulative seconds | Self seconds | Calls | Self ms/call | Total ms/call | name |
---|---|---|---|---|---|---|
该函数消耗时间占程序全部时间百分比 | 函数和上列函数累计执行时间(仅包括gprof可以监控到的函数) | 该函数自己执行时间(全部被调用次数的总共时间) | 函数被调用次数 | 函数平均执行时间 | 函数平均执行时间,包括其衍生函数 | 函数名 |
如何分析呢?性能
- 看%time列, 或者 "self ms/call"列, 这里消耗时间最多的函数就是最耗费CPU的函数了. 也是最值得优化的函数了. (消耗仅统计函数自身的代码消耗, 不统计子函数的消耗)
- 看"total ms/call"列, 找到包含子函数在内最耗时间的函数
- 从"self ms/call"列和"total ms/call"列对比可知, 若是self ms/call列的值很小,就能够推测子函数消耗时间不少
通常Flat Profile的数据就够算法竞赛或者平常的小项目的分析了。若是须要Call Graph的分析,参考网上其余的文章。优化
一些注意事项
- 一般gprof的采样周期是0.01s,统计项越接近这个值偏差可能越大。若函数的运行时间低于0.01S,统计值会显示为0。
- 多线程下,gprof只能采集主线程性能数据。缘由是gprof采用ITIMER_PROF信号,在多线程内,只有主线程才能响应该信号。解决的关键是让各个线程响应ITIMER_PROF信号,就是重写pthread_create函数。
- 通常gprof只能查看用户函数信息。若是想查看库函数的信息,须要在编译是再加入"-lc_p"编译参数代替"-lc"编译参数,这样程序会连接libc_p.a库,才能够产生库函数的profiling信息。