gprof性能测试工具
gprof
是GNU
工具链自带的性能分析工具,它通过读取性能分析文件,并与应用程序进行关联,得到应用程序性能情况,当前有两种输出模式:
- Flat profile: 显示每个函数花费的时间,以及函数调用次数。
- Call graph:显示函数调用链
使用说明
通过编译增加 -pg
选项,插入性能埋点。如果需要输出结果中带上源码,需要增加 -g
选项.
生成profile数据
以test程序为例子,运行程序,在当前目录下会生成 gmon.out
文件,供后续分析。
分析profile数据
数据分析有两种方法:
- 方法一,使用
gprof test gmon.out
,分析性能数据。如果输出内容很多,可将分析结果重定向到文件。
常用分析选项:
- -b: 输出摘要报告,不再输出统计图表中每个字段的详细描述
-p 得到每个函数占用的执行时间
-q 得到函数的时间消耗列表
- -A 得到一个带注释的“源代码清单”,指出每个函数的执行次数,需要
-g
选项编译配合。
Flat profile表格解释:
%time | Cumulative seconds | Self Seconds | Calls | Self TS/call | Total TS/call | name |
---|---|---|---|---|---|---|
该函数消耗时间占程序所有时间百分比 | 程序的累积执行时间(只是包括gprof能够监控到的函数) | 该函数本身执行时间(所有被调用次数的合共时间) | 函数被调用次数 | 函数平均执行时间(不包括被调用时间)(函数的单次执行时间) | 函数平均执行时间(包括被调用时间)(函数的单次执行时间) | 函数名 |
Call Graph 的字段含义:
Index | %time | self | Children | Total TS/call | name |
---|---|---|---|---|---|
索引值 | 函数消耗时间占所有时间百分比 | 函数本身执行时间 | 执行子函数所用时间 | 被调用次数 | 函数名 |
程序的累积执行时间只是包括gprof能够监控到的函数。工作在内核态的函数和没有加-pg编译的第三方库函数是无法被gprof能够监控到的。
- 方法二:
kprof
来解读数据,详细参考
原理简介
通过增加编译选项,在程序入口函数前,调用monstartup
函数,用于初始化gprof profile
环境。在每个函数入口处调用_mcount
函数,用于统计调用信息,注册atexit
接口,在程序正常退出时,清理相关环境,输出名为gmon.out
的性能分析文件,供后续分析。
使用注意事项
gprof
只能查看用户态函数,适合于查找用户级程序的瓶颈,无法得到程序在内核态函数的运行时间。
gprof
只能在程序正常结束退出之后才能生成性能报告。如果收到信号异常退出,则不会输出分析报告,可添加对应信号的处理函数,屏蔽处理。如果是服务型程序,可添加自定义信号,通过外部触发来模拟执行正常退出流程。
signal(SIGUSER1, sighandler)
static void sighandler(int sig_no)
{
exit(0);
}
使用方法: kill -SIGUSER1 pid.
如要监控第三方库函数执行时间,第三方库也必须是添加 –pg
选项编译。
gprof
对于CPU
密集型的程序较为适用。对于IO
密集型程序难以进行优化。
gprof
不支持多线程应用,多线程下只能采集主线程性能数据。原因是它采用ITIMER_PROF
信号,如要支持多线程分析,需要重写 pthread_create
函数,具体可点此参考