grof简介
gprof是GNU profiler工具。可以显示程序运行的“flat profile”,包括每个函数的调用次数,每个函数消耗的处理器时间。也可以显示“调用图”,包括函数的调用关系,每个函数调用花费了多少时间。还可以显示“注释的源代码”,是程序源代码的一个复本,标记有程序中每行代码的执行次数。
grof官网:
https://sourceware.org/binutils/docs-2.17/gprof/
编译程序(-pg)
使用grof时,编译程序时需要加特定选项。
编译或链接源程序的时候在编译器的命令行参数中加入
“-pg”
选项,编译时编译器会自动在目标代码中插入用于性能测试的代码片断,这些代码在程序在运行时采集并记录函数的调用关系和调用次数,以及采集并记录函数自身执行时间和子函数的调用时间,程序运行结束后,会在程序退出的路径下生成一个
gmon.out
文件。这个文件就是记录并保存下来的监控数据。可以通过命令行方式的
gprof
或图形化的
Kprof
来解读这些数据并对程序的性能进行分析。另外,如果想查看库函数的
profiling,需要在编译是再加入“-lc_p”编译参数代替“-lc”编译参数,这样程序会链接libc_p.a库,才可以产生库函数的profiling
信息。如果想执行一行一行的
profiling
,还需要加入
“-g”
编译参数。例如:
gcc -Wall -g -pg -lc_p example.c -o example
更多编译说明详见:
https://sourceware.org/binutils/docs-2.17/gprof/Compiling.html#Compiling
grof实现原理
通过在编译和链接你的程序的时候(使用 -pg 编译和链接选项),gcc 在你应用程序的每个函数中都加入了一个名为mcount ( or “_mcount” , or “__mcount” , 依赖于编译器或操作系统)的函数,也就是说你的应用程序里的每一个函数都会调用mcount, 而mcount 会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间、调用次数等等的所有信息。
参考示例
示例一:
#include <stdio.h>
int prime(int n)
{
int i;
for (i=2; i<n; i++)
{
if (n%i == 0)
return 0;
return 1;
}
}
int main(void)
{
int i, n;
n = 1000;
for (i=2; i<=n; i++)
{
if (prime(i))
printf("%d\n", i);
}
return 0;
}
编译
gcc –o test –pg test.c,运行./test 生成gmon.out
gprof命令查看gprof test gmon.out –b
示例二:
#include <stdio.h>
int a(void) {
int i=0,g=0;
while(i++<100000)
{
g+=i;
}
return g;
}
int b(void) {
int i=0,g=0;
while(i++<400000)
{
g+=i;
}
return g;
}
int main(int argc, char** argv)
{
int iterations;
if(argc != 2)
{
printf("Usage %s <No of Iterations>\n", argv[0]);
// exit(-1);
return -1;
}
else
iterations = atoi(argv[1]);
printf("No of iterations = %d\n", iterations);
while(iterations--)
{
a();
b();
}
}
编译:
gcc example1.c -pg -o example1 -O2 -lc
运行: ./example1 50000
查看:gprof example1 gmon.out -p //flat profile
gprof example1 gmon.out -q // call graph
查看带代码注释清单
编译:gcc example.c -g -pg -o example -O2 -lc
运行:./example1 50000
查看:gprof example1 gmon.out -A
输出如下:
*** File /home/martynh/profarticle/example1.c:
#include <stdio.h>
50000 -> int a(void) {
int i=0,g=0;
while(i++<100000)
{
g+=i;
}
return g;
}
50000 -> int b(void) {
int i=0,g=0;
while(i++<400000)
{
g+=i;
}
return g;
}
int main(int argc, char** argv)
##### -> {
int iterations;
if(argc != 2)
{
printf("Usage %s <No of Iterations>\n", argv[0]);
exit(-1);
}
else
iterations = atoi(argv[1]);
printf("No of iterations = %d\n", iterations);
while(iterations--)
{
a();
b();
}
}
Top 10 Lines:
Line Count
3 50000
11 50000
Execution Summary:
3 Executable lines in this file
3 Lines executed
100.00 Percent of the file executed
100000 Total number of line executions
33333.33 Average executions per line
程序性能分析工具还有全面的 Kprof, gprof2dot.py,
Kprof源码:
http://sourceforge.net/projects/kprof/ ,http://www.softpedia.com/get/Programming/Other-Programming-Files/KPROF.shtml
gprof2dot.py: http://code.google.com/p/jrfonseca/wiki/Gprof2Dot , http://www.51testing.com/html/97/13997-79952.html
以后再研究!