分类: LINUX
2010-01-08 20:05:35
关于gprof工具输出数据的含义解释:
假设有一个程序源文件hello.c内容如下:
#include
static void my_print (char *);
static void my_print2 (const char *);
main ()
{
char my_string[] = "hello world!";
my_print (my_string);
my_print2 (my_string);
my_print (my_string);
}
void count_sum()
{
int i,sum=0;
for(i=0; i<10000000; i++)
sum += i;
}
void my_print (char *string)
{
count_sum();
printf ("The string is %s ", string);
}
void my_print2 (const char *string)
{
char *string2;
int size, i,sum =0;
count_sum();
size = strlen(string);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++) string2[size -1 - i] = string;
string2[size] = '\0';
for(i=0; i<50000000; i++)
sum += i;
printf ("The string printed backward is %s ", string2);
}
1)编译生成可执行程序hello:
gcc -pg -o hello hello.c
2)需要运行一下可执行程序hello以生成gprof分析需要的数据:
$./hello
这样,会生成一个gmon.out文件供 gprof分析程序时候使用。
3)开始分析程序的执行时间:
$gprof hello
输入之后,生成如下:
【片断一】
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls us/call us/call name
69.23 0.09 0.09 1 90000.00 103333.33 my_print2
30.77 0.13 0.04 3 13333.33 13333.33 count_sum
0.00 0.13 0.00 2 0.00 13333.33 my_print
这里,描述了所有函数的执行消耗情况,每一行将代表一个函数,每一列的标题占两行,含义如下:
%
time
时间百分比,表示执行此函数所占用的时间占程序总执行时间百分比(不含其调用函数的执行时间)
cumulative
seconds (包括此函数调用其它函数花费的时间)
累计秒数,表示执行此函数花费的时间(所有次执行的时间总和,不含其调用函数的执行时间)
self 执行此函数花费的时间
seconds (调用其它函数花费的时间不计算在内)
此函数秒数,表示每次执行此函数花费的时间(仅一次执行,不含其调用函数的执行时间)
calls
调用次数,表示此函数被调用了多少次
self
us/call
此函数微妙数,表示每次调用此函数平均消耗的微秒时间(不包含此函数调用的子函数消耗时间)。
total
us/call
总微妙数,表示每次调用此函数平均消耗的总共微秒时间(包含此函数调用的子函数消耗时间)。
name
函数名
【片断二】
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) for 3.95% of 0.25 seconds
index %time self children called name
[1] 100.0 0.00 0.25 main [1]
0.16 0.03 1/1 my_print2 [2]
0.00 0.06 2/2 my_print [4]
-----------------------------------------------
0.16 0.03 1/1 main [1]
[2] 76.0 0.16 0.03 1 my_print2 [2]
0.03 0.00 1/3 count_sum [3]
-----------------------------------------------
0.03 0.00 1/3 my_print2 [2]
0.06 0.00 2/3 my_print [4]
[3] 36.0 0.09 0.00 3 count_sum [3]
-----------------------------------------------
0.00 0.06 2/2 main [1]
[4] 24.0 0.00 0.06 2 my_print [4]
0.06 0.00 2/3 count_sum [3]
-----------------------------------------------
*对于这个表(函数调用图),这个表描述了程序的函数调用关系,根据调用时间的大小对函数以及它的孩子们进行排序。
*对于这个表中的每一条记录(共4条记录),每条记录包含若干行。
*对于每一条记录中的行,
每一条记录中有一行(在最左面一列)被标上了index号,这一行的name列的函数就代表了本记录的当前函数;
每条记录内代表本记录函数的行之上的所有行,其name列的函数都是直接父函数(调用当前记录的函数的函数);
每条记录内代表本记录函数的行之下的所有行,其name列的函数都是直接子函数(被当前记录的函数调用的函数)。
*每一列,对于每一条记录来说的含义如下:
index,
代表表中每一条记录的唯一的数字(键),标在该记录当前的函数所在行,根据数字大小顺序依次排列;
另外,每一个name列处的函数名字后面也紧跟着一个index号,代表该name的函数是属于哪个index值记录的当前函数。
% time,
代表记录中当前行函数及其所有子孙(?)孩子们所消耗的时间占程序总时间的百分比,由于有些函数被排除或者其他原因可能总和不是100%.
self,
对于记录中当前函数行来说,代表执行本函数所消耗的时间(不包含它的所有子函数)。
对于记录中当前行上面行(父函数)来说,代表本函数返回到父函数花费了(父函数)多久的时间(不包括本函数的子函数所消耗的时间)。
对于记录中当前行下面行(子函数)来说,代表子函数返回到本函数花费了(本函数)多久的时间(不包括子函数的子函数所消耗的时间)。
children,
对于记录中当前函数行来说,代表本函数的所有子孙(?)函数返回到本函数所消耗(本函数)的时间。
对于记录中当前行上面行(父函数)来说,代表本函数所有子孙(?)返回到父函数,子孙们(?)消耗(父函数)的时间。
对于记录中当前行下面行(子函数)来说,代表子函数所有子孙(?)返回到本函数,那些子孙(?)消耗(本函数)的时间。
called,
对于记录中当前函数行来说,代表本函数被调用的次数,如果是递归函数则是非递归部分次数跟一个'+'号接递归调用次数。
对于记录中当前行上面行(父函数)来说,'/'左面代表该父函数调用该函数次数,'/'右面代表该函数总共被调用次数。
对于记录中当前行下面行(子函数)来说,'/'左面代表该函数调用该子函数次数,'/'右面代表该子函数总共被调用次数。
name,
对于记录中当前函数行来说,代表当前函数名加上其所属记录的index号,若该函数是某调用环一员,则环号放在函数名和index号之间。
对于记录中当前行上面行(父函数)来说,代表父函数名加其记录的index号,若父函数是某调用环一员,则环号放在父函数和index号之间。如果函数的父函数无法确定,那么在name字段打印一个`
对于记录中当前行下面行(子函数)来说,代表子函数名加其记录的index号,若子函数是某调用环一员,则环号放在子函数和index号之间。
如果在调用图中存在任何环,那么会有一个记录来记录整个环。这个记录描述了环中谁做为谁的父函数调用了谁。环中,called字段'+'后指名了这个函数在环内部(递归)调用的次数,called字段其它部分(应该在+之前),指出环外函数对本函数的(非递归)调用次数。例如如下:
index % time self children called name
0.16 0.03 1/1 main [2]
[1] 100.0 0.16 0.03 1 my_print2 [1]
0.03 0.00 1/1 count_sum [3]
-----------------------------------------------
[2] 100.0 0.00 0.19 main [2]
0.16 0.03 1/1 my_print2 [1]
0.00 0.00 1/1 fact [4]
-----------------------------------------------
0.03 0.00 1/1 my_print2 [1]
[3] 15.8 0.03 0.00 1 count_sum [3]
-----------------------------------------------
10 fact [4]
0.00 0.00 1/1 main [2]
[4] 0.0 0.00 0.00 1+10 fact [4]
10 fact [4]
-----------------------------------------------
这里的fact就是阶乘的递归调用,代码我省略了。
--------
这里红字部分了解的不透彻,不透彻所以看不懂,有谁能指导一下吗?