LinuxLinux学习之路嵌入式

Linux实用工具-gprof

2020-06-16  本文已影响0人  QuietHeart

功能

gprof可以用来分析程序的性能.

描述

常用的gprof命令选项:

举例

关于gprof工具输出数据的含义解释:

假设有一个程序源文件hello.c内容如下:

#include <stdio.h>

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
                                                 <spontaneous>
[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]
-----------------------------------------------

如果在调用图中存在任何环,那么会有一个记录来记录整个环。这个记录描述了环中谁做为谁的父函数调用了谁。环中,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]
-----------------------------------------------
                                                 <spontaneous>
[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就是阶乘的递归调用,代码我省略了。

注: 这里红字部分了解的不透彻,其中标记为 待理解?

补充

这里补充说明不明白的地方:
cumulative seconds实际是:一个时间和,它的原始解释如下:

cumulative a running sum of the number of seconds accounted 
seconds for by this function and those listed above it.

也就是说, "第一行的self"="cumulative", "以后行的cumulative"="self+上一行的cumulative"

再补充一点,对于文中的 待理解? ,这样理解:

说的似乎很复杂,实际直接看图自己理解,是很简单的,不要以为这个工具的输出多么复杂,要以简单的思想来分析它的输出含义。

上一篇下一篇

猜你喜欢

热点阅读