GNU profiler(gprof)


GNU profiler(gprof)是GNU profiler工具。它可以为Linux平台上的程序精确分析性能瓶颈,它能够记录每个函数的调用次数,每个函数消耗的处理器时间,还能够显示“调用图”,包括函数的调用关系。能够为我们改进应用程序的性能提供很多有利的帮助。
原理
通过在编译和链接程序的时候使用-pg选项(编译和链接过程都需要),当我们使用"-pg"选项编译程序后,gcc会做三个工作:
程序的入口处(main函数之前)插入monstartup函数的调用代码,完成profile的初始化工作,包括分配保存信息的内存以及设置一个clock信号处理函数
在每个函数的入口处插入_mcount函数的调用代码,用于统计函数的调用信息:包括调用时间、调用次数以及调用栈信息
在程序退出处(注册atexit()函数),插入_mcleanup()函数的调用代码,负责将profile信息输出到gmon.out中。
命令
-b 不再输出统计图表中每个字段的详细描述。
-q 只输出函数的调用图(Call graph的那部分信息)。
-p 只输出函数的时间消耗列表。
-e Name 不再输出函数Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志,一个 -e 标志只能指定一个函数。
-E Name 不再输出函数Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数Name 及其子函数所用的时间。
-f Name 输出函数Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。
-F Name 输出函数Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。
-z 显示使用次数为零的例程(按照调用计数和累积时间计算)。
使用
在编译和链接时,加上-pg选项。
执行编译的二进制程序
程序正常退出后,在运行目录下 生成gmon.out文件。如果原来有gmon.out 文件,将会被覆盖。
用gprof工具分析gmon.out文件。
gprof输出分析
在gmon.out文件产生之后,可以通过GNU binutils中提供的工具gprof来分析数据,转换成容易阅读、理解的格式。一般用法:
# gprof Bin-file gmon.out >report.txt
其中,Bin-file指的是所运行的程序(也可以是程序调用到的库文件),gmon.out就是前面所输出的那个文件,report.txt就是生成的分析报告了。Gprof提供了丰富的参数选项,以控制报告输出的内容。
各个字段的含义如下:
%time 该函数消耗时间占程序所有时间的百分比
Cumulative seconds 累积执行时间。执行这个函数所消耗的时间,加上其上列函数消耗的时间总和
Self seconds 函数自身消耗的时间(所有调用时间总和),列表首先以这个值的大小排序
Calls 函数被调用的次数,如果某个函数从未被调用,那么这个字段为空
Self Ts/call函数自身的平均执行时间
Total Ts/call函数及其衍生函数调用的平均时间
Name 函数名
一些弱点
只有进程退出才能生成gmon.out文件,用起来还是有些不方便,Gprof对多线程支持不好,因为gprof用ITIMER_PROF信号,而只有主线程才能处理这个信号。它只能分析应用程序在运行过程中所消耗掉的用户时间,无法得到程序内核空间的运行时间。对内核态的调用分析无能为力。如果程序系统调用比率比较大,就不适合。此外,时间是通过采样分析得到的,结果精度不高,如果执行时间很少,那么可能采不到样,输出时,结果就忽略了,这也是很多地方看到的时间都是0.00的原因。
最新版本:2.3
项目主页:https://sourceware.org/binutils/
原理
通过在编译和链接程序的时候使用-pg选项(编译和链接过程都需要),当我们使用"-pg"选项编译程序后,gcc会做三个工作:
程序的入口处(main函数之前)插入monstartup函数的调用代码,完成profile的初始化工作,包括分配保存信息的内存以及设置一个clock信号处理函数
在每个函数的入口处插入_mcount函数的调用代码,用于统计函数的调用信息:包括调用时间、调用次数以及调用栈信息
在程序退出处(注册atexit()函数),插入_mcleanup()函数的调用代码,负责将profile信息输出到gmon.out中。
命令
-b 不再输出统计图表中每个字段的详细描述。
-q 只输出函数的调用图(Call graph的那部分信息)。
-p 只输出函数的时间消耗列表。
-e Name 不再输出函数Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志,一个 -e 标志只能指定一个函数。
-E Name 不再输出函数Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数Name 及其子函数所用的时间。
-f Name 输出函数Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。
-F Name 输出函数Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。
-z 显示使用次数为零的例程(按照调用计数和累积时间计算)。
使用
在编译和链接时,加上-pg选项。
执行编译的二进制程序
程序正常退出后,在运行目录下 生成gmon.out文件。如果原来有gmon.out 文件,将会被覆盖。
用gprof工具分析gmon.out文件。
gprof输出分析
在gmon.out文件产生之后,可以通过GNU binutils中提供的工具gprof来分析数据,转换成容易阅读、理解的格式。一般用法:
# gprof Bin-file gmon.out >report.txt
其中,Bin-file指的是所运行的程序(也可以是程序调用到的库文件),gmon.out就是前面所输出的那个文件,report.txt就是生成的分析报告了。Gprof提供了丰富的参数选项,以控制报告输出的内容。
各个字段的含义如下:
%time 该函数消耗时间占程序所有时间的百分比
Cumulative seconds 累积执行时间。执行这个函数所消耗的时间,加上其上列函数消耗的时间总和
Self seconds 函数自身消耗的时间(所有调用时间总和),列表首先以这个值的大小排序
Calls 函数被调用的次数,如果某个函数从未被调用,那么这个字段为空
Self Ts/call函数自身的平均执行时间
Total Ts/call函数及其衍生函数调用的平均时间
Name 函数名
一些弱点
只有进程退出才能生成gmon.out文件,用起来还是有些不方便,Gprof对多线程支持不好,因为gprof用ITIMER_PROF信号,而只有主线程才能处理这个信号。它只能分析应用程序在运行过程中所消耗掉的用户时间,无法得到程序内核空间的运行时间。对内核态的调用分析无能为力。如果程序系统调用比率比较大,就不适合。此外,时间是通过采样分析得到的,结果精度不高,如果执行时间很少,那么可能采不到样,输出时,结果就忽略了,这也是很多地方看到的时间都是0.00的原因。
最新版本:2.3
项目主页:https://sourceware.org/binutils/