用好binutils之gporf


gporf被称为GNU简档器,是binutils中的一个程序。这个程序可以帮我们找出程序运行时需要处理时间最长的函数。通过它我们可以有效的改善我们程序的效率。

为了有效的使用我们的gprof工具,必须确保参数-pg编译希望监视的函数 ,用这个参数编译源代码,会为程序的每个函数插入对mcount自子例程的调用,当运用程序运行时,mcount子例程创建一个调用图表简档文件,即gmon.out,它包含了程序中每个函数的计时信息。
程序测试完之后,就可以使用gprof程序来查看调用图表简档文件,gprof的能够输出以下几项内容:
    一般简档报告(flat profile),显示每个函数在你的程序中花费的时间和被调用的次数。
    调用图表(call graph),显示对每个函数的,调用者和被调用者以及次数。每个函数的子路径执行时间的估计。
    源代码注释列表(annotate source listing),是源程序的一份copy,里面标明了每行执行时间。

下面我们举个例子,这个程序的名字是test.c
#include <stdio.h>

void fun1()
{
    int i,j;
    for (i=0;i<10000;i++)
        j=i;
}

void fun2()
{
    int i,j;
    fun1();
    for (i=0;i<40000;i++)
        j=i;
}

int main()
{
    int i;
   
    for(i=0;i<100;i++)
        fun1();
   
    for(i=0;i<1000;i++)
        fun2();
   
    return(0);
}
主程序有两个循环,一个调用fun1()100次,一个调用fun2()1000次,而在每个函数fun2()又都调用函数fun1(),所以fun1()总共调用了1100次,但还是fun2()占了更多的时间。
下一步使用-pg参数编译程序,以便能够使用gprof。编译之后运行程序。
$gcc -o test test.c -pg
$./test
程序运行结束后会产生gmon.out调用图表文件,查看一下生成的文件
$ls -al gmon.out
-rw-rw-r-- 1 secularbird secularbird 464 2007-10-16 22:38 gmon.out
接下来运行gprof,由于产生的输出是到标准输出的,所以我们进行一次重定向
$gprof test > gprof.txt
注:gprof的默认参数是 -p -g对于不同的系统可能有些不同。

下面是我gprof.txt文件中的一部分,各人的结果可能有点不同
Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  us/call  us/call  name   
 85.31      0.28     0.28     1000   281.51   327.21  fun2
 15.23      0.33     0.05     1100    45.70    45.70  fun1
由此可见和我们之前分析的一样,fun1调用了1100次,fun2被调用了1000次,fun2占用了85.31%即大部分的时间。
             Call graph (explanation follows)


granularity: each sample hit covers 2 byte(s) for 3.01% of 0.33 seconds

index % time    self  children    called     namea
                                                 <spontaneous>
[1]    100.0    0.00    0.33                 main [1]
                0.28    0.05    1000/1000        fun2 [2]
                0.00    0.00     100/1100        fun1 [3]
-----------------------------------------------
                0.28    0.05    1000/1000        main [1]
[2]     98.6    0.28    0.05    1000         fun2 [2]
                0.05    0.00    1000/1100        fun1 [3]
-----------------------------------------------
                0.00    0.00     100/1100        main [1]
                0.05    0.00    1000/1100        fun2 [2]
[3]     15.2    0.05    0.00    1100         fun1 [3]
在call gprah中可以看出index[1]在main函数中fun1总共被调用了100次,fun2总共被调用了1000次,
index[2]在整个的程序中,fun2总共被调用了1000次,而fun2总共调用了fun1 1000次。
index[3]在整个的程序中,main调用100次的fun1,fun2调用了1000次的fun1,fun1总共被调用了1100次
以上内容仅供参考,实际情况可以设置gprof参数得到个人所需的内容。

参考资料
    《Professional Assemble language》Richard Blum著
    man gprof


 

你可能感兴趣的:(util)