IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    gprof学习笔记

    一根稻草发表于 2015-05-21 00:00:00
    love 0

    1. gprof简介


    gprof(GNU Profile)是一个C/C++程序性能分析工具,它能够计算程序运行中各个函数消耗的时间, 可以帮助程序员找出众多函数中耗时最多的函数。 产生程序运行时候的函数调用关系图(call graph),包括调用次数,可以帮助程序员分析程序的运行流程。时间计算准确度很高,对函数执行次数的统计是100%正确的,但是对函数执行时间的统计是通过采样平率估算的,存在一定的偏差。

    2. 测试程序


    测试程序使用test_prof.c

    #include
    
    void new_func1(void){
        printf("\n Inside new_func1()\n");
        int i = 0;
        for(;i<0xffffffee;i++);
    }
    
    void func1(void){
        printf("\n Inside func1 \n");
        int i = 0;
        for(;i<0xffffffff;i++);
        new_func1();
    }
    
    static void func2(void){
        printf("\n Inside func2 \n");
        int i = 0;
        for(;i<0xffffffaa;i++);
    }
    
    int main(void){
        printf("\n Inside main()\n");
        int i = 0;
        for(;i<0xffffff;i++);
        func1();
        func2();
    
        return 0;
    }
    

    编译test_prof.c,一定要加上-pg参数

        gcc test_prof.c -pg -o test_prof
    

    如果编译过程和链接过程分开的话,那么在编译过程和链接过程都要使用-pg参数

        gcc -c test_prof.c -pg
        gcc -pg test_prof.o -o test_prof
    

    如果编译过程没有-pg参数,那么不会产生函数调用图,如果链接过程不使用-pg参数,那么根本不会生成gmon.out文件.

    运行./test_prof就会产生gmon.out文件,下面使用gprof命令对gmon.out文件进行分析。

    3. gprof使用说明


    本节根据一些典型的使用案例,来说明不同的参数作用。

    0.无参数选项时,会输出函数占用时间, 函数调用图,这是两个表格,输出信息中还包括对表格的说明信息

      gprof test_prof gmon.out
      鉴于输入信息实在太多,占用篇幅太多,约有150行,这里不于显示。
    

    默认情况下输出的信息比较全面, 但是大部分都是无用信息,干扰正常的判断,所以下面要介绍一些参数,可以只打印你需要关心的部分。

    1.查看程序的函数调用记录数目,那么可以使用-i输出gmon.out的简要信息

    gprof test_prof gmon.out -i
        File `gmon.out' (version 1) contains:
        1 histogram record
        3 call-graph records
        0 basic-block count records
    

    2.输出函数调用关系图

    gprof test_prof gmon.out -q -b 
                    Call graph
    
        granularity: each sample hit covers 2 byte(s) for 0.03% of 32.55 seconds
    
        index % time    self  children    called     name
                                                         
        [1]    100.0    0.04   32.51                 main [1]
                       10.73   10.88       1/1           func1 [2]
                       10.89    0.00       1/1           func2 [3]
        -----------------------------------------------
                       10.73   10.88       1/1           main [1]
        [2]     66.4   10.73   10.88       1         func1 [2]
                       10.88    0.00       1/1           new_func1 [4]
        -----------------------------------------------
                       10.89    0.00       1/1           main [1]
        [3]     33.5   10.89    0.00       1         func2 [3]
        -----------------------------------------------
                       10.88    0.00       1/1           func1 [2]
        [4]     33.4   10.88    0.00       1         new_func1 [4]
        -----------------------------------------------
    
        Index by function name
    
           [2] func1                   [1] main
           [3] func2                   [4] new_func1
    

    选项-b是为了屏蔽无用的表格说明信息,表头的含义分别如下(两个上下虚线内的部分作为一条记录)

    index   : 函数序号,**一定要注意序号所在的行,在两条虚线内,序号上面是该函数的parent,序号的下面是该函数的children**
    % time  : 花费时间占用百分比
    self    : 该函数所花费的时间,单位是秒
    children: 它的children函数所花费的总时间    
    called  : 调用次数,对于其parent函数行,'/'之前表示paraent调用该函数的次数,'/'之后表示该函数被调用的总次数
                      对于其children函数行, '/'之前表示该函数调用children的次数,'/'之后表示其children被调用的总次数
    name    : 函数名
    

    实现同样功能的其它参数选项有

        gprof test_prof gmon.out --graph -b
        gprof test_prof gmon.out --no-flat-profile -b       
        gprof test_prof gmon.out -P -b      
    

    3.只输出各函数花费的时间

        gprof test_prof gmon.out -p -b  
            Flat profile:
    
            Each sample counts as 0.01 seconds.
              %   cumulative   self              self     total           
             time   seconds   seconds    calls   s/call   s/call  name    
             33.82     10.89    10.89        1    10.89    10.89  func2
             33.79     21.78    10.88        1    10.88    10.88  new_func1
             33.32     32.51    10.73        1    10.73    21.62  func1
              0.13     32.55     0.04                             main
    

    每一列所表示的含义为

      % time            : 该函数花费时间的百分比
      cumulative seconds: 从表格第一条记录到该记录累加的时间总和
      self  seconds     : 该函数自身所花费的时间,不包括其children运行时间,整个表格是根据这一列从高到低进行排序的   
      calls             : 该函数被调用次数
      self  s/call      : 该函数自身每次调用(不包括children运行)的平均时间,即前两列相除  
      total  s/call     : 该函数平均每次运行所需要的时间(包括children运行)
      name              : 函数名
    

    实现同样功能的其它参数选项有

        gprof test_prof gmon.out --flat-profile -b
        gprof test_prof gmon.out --no-graph -b
        gprof test_prof gmon.out -Q -b
    

    4.只输出func2函数相关的信息

    gprof test_prof gmon.out -pfunc2 -b

        Flat profile:
    
        Each sample counts as 0.01 seconds.
          %   cumulative   self              self     total           
         time   seconds   seconds    calls   s/call   s/call  name    
        103.21     10.89    10.89        1    10.89    10.89  func2
    

    gprof test_prof gmon.out -qfunc2 -b

                            Call graph
    
            granularity: each sample hit covers 2 byte(s) for 0.03% of 32.55 seconds
    
            index % time    self  children    called     name
                           10.89    0.00       1/1           main (1)
            [3]     33.5   10.89    0.00       1         func2 [3]
            -----------------------------------------------
    
            Index by function name
    
               (2) func1                   (1) main
               [3] func2                   (4) new_func1
    

    4. 性能优化方面的资料

    1. 性能调优攻略
    2. 性能分析工具gprof介绍
    3. 使用 TPTP 对 Eclipse 插件进行性能剖析和调优
    4. 使用Codan在Eclipse中执行C/C++分析工具
    5. Google performance Tools (gperftools)使用心得


沪ICP备19023445号-2号
友情链接