一. 概要
1. Gprof 是在运行中收集程序的统计信息。
程序的运行方式会严重影响统计的信息结果。因为不同的执行路径下,程序的行为方式会有很大的差别。
2. Gprof 使用步骤
(1) 编译链接程序的时候,使能Gprof
(2) 执行程序生成profile data file
(3) 使用Gprof分析profile data
3. 输出格式
(1) flat profile
每一个函数花费了多少时间,每一个函数被调用了多少次
(2) call graph
对每一个函数来说,哪个函数调用了它,多少次;它调用了哪些个函数,多少次
这个函数花费了多少时间,它调用的函数花费了多少时间
(3) annotated source
生成一份源代码的拷贝,标注出每一个block被执行了多少次
二. 为 Gprof 编译程序
1. 给GNU Tools 传递PG选项
gcc -g -pg .............
编译器和连接器都需要加上-pg 选项
2. 执行程序
程序执行结束后,会生成gmon.out 统计文件,这个就是profiler data file。
注意:只有在程序正常终止的时候,才会生成这个文件。也就是说,程序必须是从exit或者return终止的。
3. 分析生成结果
gprof [Options] <可执行文件>
三. Gprof 的输出格式
G平日哦方可生成四种格式的统计结果,其中的line-by-line的输出,已经转移到gconv工具上。
所以目前的Gprof主要是三种格式的输出。
1. Flat Profile:
- % the percentage of the total running time of the
-
time program used by this function.(在整个程序运行时间中,
- 这个函数运行时间所占的百分比)
-
-
cumulative a running sum of the number of seconds accounted
-
seconds for by this function and those listed above it.
- (这个函数和列在它之前的函数,以秒为单位运行时间的总和)
-
-
self the number of seconds accounted for by this
-
seconds function alone. This is the major sort for this
-
listing.(这个函数自身运行时间的总和,以秒为单位)
-
-
calls the number of times this function was invoked, if
-
this function is profiled, else blank.(这个函数
- 被调用的总次数)
-
-
self the average number of milliseconds spent in this
-
ms/call function per call, if this function is profiled,
-
else blank.(这个函数每次被调用的平均时间,以毫秒为单位)
-
-
total the average number of milliseconds spent in this
-
ms/call function and its descendents per call, if this
-
function is profiled, else blank.(这个函数和在它内部调用的
- 函数,每次被调用的平均运行时间)
-
-
name the name of the function. This is the minor sort
- for this listing. The index shows the location of
- the function in the gprof listing. If the index is
-
in parenthesis it shows where it would appear in
- the gprof listing if it were to be printed.
2. Call Graph
granularity: each sample hit covers 2 byte(s) for 20.00% of 0.05 seconds
index % time self children called name
[1] 100.0 0.00 0.05 start [1]
0.00 0.05 1/1 main [2]
0.00 0.00 1/2 on_exit [28]
0.00 0.00 1/1 exit [59]
-----------------------------------------------
0.00 0.05 1/1 start [1]
[2] 100.0 0.00 0.05 1 main [2]
0.00 0.05 1/1 report [3]
-----------------------------------------------
0.00 0.05 1/1 main [2]
[3] 100.0 0.00 0.05 1 report [3]
0.00 0.03 8/8 timelocal [6]
0.00 0.01 1/1 print [9]
0.00 0.01 9/9 fgets [12]
0.00 0.00 12/34 strncmp [40]
0.00 0.00 8/8 lookup [20]
0.00 0.00 1/1 fopen [21]
0.00 0.00 8/8 chewtime [24]
0.00 0.00 8/16 skipspace [44]
-----------------------------------------------
[4] 59.8 0.01 0.02 8+472 [4]
0.01 0.02 244+260 offtime [7]
0.00 0.00 236+1 tzset [26]
-----------------------------------------------
虚线分割的每一个部分叫做一个entity,用来描述一个函数或者一个cycle。
其中每一个以 [数字] 开始的行叫做 primary line,这个entity主要就是描述它的。
在 primary line 之前的行显示的是调用这个函数的函数,也就是caller。在它之后
的是这个函数调用的函数,也就是subroutine。
2.1 Primary Line
index % time self children called name
...
[3] 100.0 0.00 0.05 1 report [3]
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- index
- Entries are numbered with consecutive integers. Each function therefore has an index number, which appears at the beginning of its primary line.
-
- Each cross-reference to a function, as a caller or subroutine of another, gives its index number as well as its name. The index number guides you if you wish to look for the entry for that function.
-
-
% time
- This is the percentage of the total time that was spent in this function, including time spent in subroutines called from this function.(花费在这个函数中的时间在整个程序全部运行时间中的百分比,其中包括花费在这个函数调用的子函数中的时间)
-
-
The time spent in this function is counted again for the callers of this function. Therefore, adding up these percentages is meaningless.(在这个函数的调用函数caller中,这个函数的运行时间,还会被计算在内,所以将这些百分数加在一起没有意义)
-
-
self
- This is the total amount of time spent in this function. This should be identical to the number printed in the seconds field for this function in the flat profile.(这个函数自身花费的时间。这个数应该和Flat Profile中的记录一样)
-
-
children
- This is the total amount of time spent in the subroutine calls made by this function. This should be equal to the sum of all the self and children entries of the children listed directly below this function. (花费在这个函数调用的所有函数的总时间。这个数应该和列在这个函数下面的子函数的全部 self 和 children之和相等)
-
called This is the number of times the function was called.(这个函数被调用的次数)
-
-
If the function called itself recursively, there are two numbers, separated by a `+'. The first number counts non-recursive calls, and the second counts recursive calls.(如果这个函数被循环调用,这里就会有两个被“+”分隔的数字,第一个数字表示非递归调用的次数,第二个表示递归调用的次数)
-
-
In the example above, the function report was called once from main.
-
-
name
- This is the name of the current function. The index number is repeated after it.
-
-
If the function is part of a cycle of recursion, the cycle number is printed between the function's name and the index number . For example, if function gnurr is part of cycle number one, and has index number twelve, its primary line would be end like this:
-
-
gnurr [12]
- 如果这个函数是一个循环递归的一部分,循环编号将会打印在函数名和函数索引号之间。例如:如果函数gnurr是循环一的一部分,并且它的索引号是12,它的primary line就应该如下:
- gnurr [12]
2.2 Lines for a function's caller
index % time self children called name
...
0.00 0.05 1/1 main [2]
[3] 100.0 0.00 0.05 1 report [3]
- self
- An estimate of the amount of time spent in report itself when it was called from main.
- (report自己花费的时间)
-
-
children
-
An estimate of the amount of time spent in subroutines of report when report was called from main.
- (report的子函数花费的总时间)
-
-
The sum of the self and children fields is an estimate of the amount of time spent within calls to
- report from main.
-
-
called
- Two numbers: the number of times report was called from main, followed by the total number of
- nonrecursive calls to report from all its callers.(两个数字:第一个,从main函数中调用report的次数,
- 第二个,report被非递归形式调用的总次数)
-
-
name and index number
-
The name of the caller of report to which this line applies, followed by the caller's index number.
-
-
Not all functions have entries in the call graph; some options to gprof request the omission of certain
- functions. When a caller has no entry of its own, it still has caller-lines in the entries of the
- functions it calls.(不是所有的函数在call graph中都有entity)
-
-
If the caller is part of a recursion cycle, the cycle number is printed between the name and the index
- number.(如果caller是一个递归循环的一部分,循环编号会打印在caller的名字和编号之间)
如果caller不能确定,就会出现作为caller。
====== to be continue ======
阅读(4420) | 评论(0) | 转发(0) |