-
2007-08-30
使用gprof剖析代码解决性能问题 - [LBE]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://gosman.blogbus.com/logs/8015225.html
原文:Use gprof to check your codes for performance issues
作者:mysurface
译者:gosman(lianmingchang2008#gmail.com)
来自:http://gosman.blogbus.com
版本:V 1.0.0
时间:2007-8-30
通过阅读IBM DevelopWorks上的使用 GNU profiler 来提高代码运行速度,我掌握了使用gprof来分析代码的性能瓶颈,以减轻我工作的技术。下面就来分享一下我的经验。
我们先看看GNU profiler工作的几个简单步骤。
为了使用gprof,只需在用gcc编译C/C++代码时加上-pg选项。假设要编译的源代码是gp-test.c。
gcc -pg -g2 -o gp-test{,.c}-pg是启用gprof,-g2设置调试模式为2,-o指定二进制输出,我使用了大括号扩展来减少我的输入。
接着运行可执行文件,将产生gmon.out。
./gp-test有了gmon.out,我们就可以使用gprof来剖析我们的代码。
gprof gp-test gmon.out > result.txt我倾向于把输出保存为一个文件'result.txt',以利于将来的比较和分析。
让我们举一个C例子代码,试着找到关键点。
#include
int twoD[10000][10000]={0};
int update_d1()
{
int i,k=0;
for (i=0;i<10000;i++)
twoD[i][1]=k++;
}
int update_d2()
{
int i,k=0;
for (i=0;i<10000;i++)
twoD[1][i]=k++;
}
int main(int argc, char * argv[])
{
int i,j,k=0;
if (argc!=2)
return -1;
if (*(argv[1])=='1')
update_d1();
else if (*(argv[1])=='2')
update_d2();
else
printf("\nInvalid value %s\n",argv[1]);
return 1;
}函数update_d1()和update_d2()循环一样的次数来访问二维数组。设这二维数组为twoD[row][column],update_d1()访问行(row),update_d2()访问列(column)。我们发现这两个函数的运行时间差很大。让我们用gprof剖析一下吧。
gcc -pg -g -o gp-test{,.c}
./gp-test 1
gprof gp-test gmon.out > t1
./gp-test 2
gprof gp-test gmon.out > t2观察剖析结果:
using update_d1() :
% cumulative self self total
time seconds seconds calls ms/call ms/call name
100.52 0.06 0.06 1 60.31 60.31 update_d1
using update_d2() :
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 update_d2update_d1()花费0.06秒,update_d2()少于0.01秒,为什么呢?
让我们再看看这个二维数组twoD[row][column]。这个数组在物理上映射为一整块内存,而不是按行列排列。这内存块以0行1列开始,而第一行第一列实际是第10001块。
想象一下update_d1()怎样访问内存?为了访问每行,你需要越过10000块,而update_d2()可以直接访问那10000块。这就是延迟的原因。
随机文章:
Bash 补全技巧 2007-10-31grep输出匹配前后多行 2007-09-07需要超级用户权限的脚本 2007-09-04标签页浏览的文件管理器 2007-09-02查找公共IP地址 2007-08-27
收藏到:Del.icio.us







