曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4735|回复: 1
打印 上一主题 下一主题

GNU简档程序 gprof

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2009-11-25 01:33:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GNU 简档器 (gprof) 是 binutils 包中的一个程序。这个程序的作用是用来分析程序的执行和确定应用程序中的“热点”在什么位置。

应用程序的“热点”是指程序运行时需要最多处理时间的函数。通常,它们是最为数学密集型的函数,但情况也不尽如此,像 I/O 密集型函数也会增加处理时间。

gprof 的参数有很多,这一大堆的参数可以分为 3 组:
      输出格式参数
      分析参数
      杂项参数

下表是输出格式参数,它们允许修改 gprof 生成的输出

参数
描述
-A
显示所有函数的源代码,或者只显示指定函数的源代码
-b
不显示解释分析字段的详细输出
-C
显示所有函数的总计数,或者只显示指定函数的总计数
-i
显示简档数据文件的摘要信息
-I
指定查找源文件的搜索目录清单
-J
不显示注解的源代码
-L
显示源文件名的完整路径名称
-p
显示所有函数的一般简档,或者只显示指定函数的一般简档
-P
不输出所有函数的一般简档,或者不显示指定函数的一般简档
-q
显示调用图表分析
-Q
不显示调用图表分析
-y
在单独的输出文件中生成注解的源代码
-Z
不显示函数的总计数和被调用的次数
--function-reordering
按照分析显示建议的函数的重排序
--file-ordering
按照分析显示建议的目标文件重排序
-T
按照传统的BSD样式显示输出
-w
设置输出行的宽度
-x
在函数之内显示被注解的源代码中的每一行
-demangle
在显示输出时 C++ 符号被还原

下表为“分析参数”,它们修改 gprof 分析包含在分析文件中的数据的方式
参数
描述
-a
不分析静态声明(私有)的函数的信息
-c
分析程序中永远不会被调用的子函数的信息
-D
忽略已知不是函数的符号(只在Solaris 和 HP操作系统上用)
-k
不分析匹配开头和结尾的 symspec 的函数
-l
按行分析程序,而不是按函数
-m
只分析被调用超过指定次数的函数
-n
只分析指定的函数的时间
-N
不分析指定的函数的时间
-z
分析所有函数,即使是从不被调用的那些

下表是“杂项参数”,这些参数也是用来修改 gprof 的行为,但不适合放在输出参数组或者分析参数组之内

参数
描述
-d
使 gprof 处于调式模式中,指定数字化的调试级别
-O
指定简档数据文件的格式
-s
使 gprof 只在简档数据文件中汇总数据
-v
输出 gprof 的版本

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2009-11-25 10:23:20 | 只看该作者

举例说明 gprof 使用方法

为了演示 gprof 程序,下面使用一个 gprof.c 文件:
#include <stdio.h>

void function1()
{
    int i, j;
    for (i = 0; i < 100000; i++)
        j += i;
}

void function2()
{
    int i, j;
    function1();
    for (i = 0; i < 200000; i++)
        j = i;
}

int main()
{
    int i, j;
    for (i = 0; i < 100; i++)
        function1();

    for (i = 0; i < 50000; i++)
        function2();

    return (0);
}
这个程序有两个循环: function1() 100 次调用; function2() 调用 50 000 次。每个函数只执行简单的循环,但是每次调用 function2() 时,它会调用 function1() 。

为了使 gprof 能够执行,在编译程序时要使用 -pg 参数:
gcc -o gprof gprof.c -pg

接着,运行生成的 gprof 文件,运行后会在同一目录下创建 gmon.out 调用图表简档文件:
./gprof
beyes@beyes-groad:~/programming$ ls -al gmon.out
-rw-r--r-- 1 beyes beyes 424 2009-11-24 20:17 gmon.out

这时候,可以执行 gprof 程序,并且把结果保存到一个文件中:
gprof gprof > gprof.txt
注意,上面命令中没有引用 gmon.out 文件!gprof 自动使用位于相同目录下的 gmon.out 文件。这里产生的 gprof.txt 是完整的 gprof 报告。

看一下 gprof.txt 中的内容,以下不把所有的内容列出,但会解释两个生成的简表样列。下面是第一个表:

图表解释:                                                                             
%
time
表示两个函数在整个程序耗时中所占据的时间百分比。容易看到,function2() 占了 61.05% ,而 function1() 占了 38.95% 。

cumulative
seconds
累积时间。累积时间表示,这个函数在整个程序中的所有耗时,这个耗时包括独自运行时间以及被别的函数调用的运行时间。

self
seconds
自身独立运行时间。自身运行时间是指由主函数调用,单独的运行时间。function1() 独立运行时间为 12.43s ,它也被 function2() 调用,被 function2() 调用(50000次) 是 (31.91-12.43=19.48)s 。

self
被调用的次数。

self
us/call
自身独立运行所需平均时间,不包括里面所包含的子函数。

total
us/call
包括自身运行平均时间以及函数里面所包含子函数运行的平均时间。由 function2() 可以看到,它的 toal us/call 为 637.70us;它的 self us/call 为 389.60us ,而 function1() 的 self us/call 为 248.10 ,也就是 389.60 + 248.10 = 637.70 。

name
函数名


另一个简档如下图所示(显示各个函数的细分时间,以及函数是如何被调用的):


上图中:
index
表示要分析的索引号。这个索引号和后面要分析的函数所标示的数字 [x] 是一致的---为的是突出显示。

% time
是函数自身运行的时间与(函数自身运行时间+作为子函数被其他函数调用所花掉的时间)的比值。比如上面,function1() 自身运行时间是 12.43s ,它被 function2() 调用时,所花费的时间为 19.48s (也是 function2() 的时间),所以,这个比值就是 12.43/31.91=39.0% 。由于考虑到其他的一些因素,这个比值不会达到 100%,而会出现如 99.9% 这样的精确值。

self
函数自身所耗费时间。

children
函数中的子函数所耗费的时间。

called
被调用的次数。这里的次数有两个数值,用 / 号隔离开来。以上面图示说明:
当分析 function2() 时,它的这一栏为 50000 , 而 main 的这一栏为 50000/50000 。这表示 function2() 被调用了 50000 次,而从 main 的角度来看,在它看到的 50000 调用中(/ 号右边数值),function2() 被调用了 50000 次;
当分析 function1() 时,它的这一栏为 50100,  而 main 的这一栏为 100/50100 。这表示 function1() 在 main 看来,在 function1() 所发生的 50100 次的调用中,它直接看到的是 100 次;再看 function2() 这一栏表示为 50000/50100 ,也就是说,从 function2() 看过去,在 function1() 的 50100 次调用中,function1() 作为子函数,在它这里被调用了 50000 次。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-15 08:11 , Processed in 0.067244 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表