perflab——smooth函数优化

可以看到有一个很严重的问题,每次执行的时候都调用了avg函数,观察avg函数的代码又发现它调用了其他的函数,这样频繁的函数调用就决定了程序运行的速度,所以要优化函数,首先在smooth函数中不要调用avg(),自己写求平均的函数,要分三种情况,一是图像的四个角落,二是四条边界上的点,三是一般情况。这样过后可以发现性能有了大幅度的提高。代码如下: 

char smooth_descr[] = "smooth: Current working version";
void smooth(int dim, pixel *src, pixel *dst) 
{
    int i,j;
    //no using avg()

    //corners
//the top left corner
    dst[RIDX(0,0,dim)].red=(src[RIDX(0,0,dim)].red+src[RIDX(1,0,dim)].red+src[RIDX(0,1,dim)].red+src[RIDX(1,1,dim)].red)>>2;
    dst[RIDX(0,0,dim)].blue=(src[RIDX(0,0,dim)].blue+src[RIDX(1,0,dim)].blue+src[RIDX(0,1,dim)].blue+src[RIDX(1,1,dim)].blue)>>2;
    dst[RIDX(0,0,dim)].green=(src[RIDX(0,0,dim)].green+src[RIDX(1,0,dim)].green+src[RIDX(0,1,dim)].green+src[RIDX(1,1,dim)].green)>>2;
//the top right corner
    dst[RIDX(0,dim-1,dim)].red=(src[RIDX(0,dim-1,dim)].red+src[RIDX(1,dim-1,dim)].red+src[RIDX(0,dim-2,dim)].red+src[RIDX(1,dim-2,dim)].red)>>2;
    dst[RIDX(0,dim-1,dim)].blue=(src[RIDX(0,dim-1,dim)].blue+src[RIDX(1,dim-1,dim)].blue+src[RIDX(0,dim-2,dim)].blue+src[RIDX(1,dim-2,dim)].blue)>>2;
    dst[RIDX(0,dim-1,dim)].green=(src[RIDX(0,dim-1,dim)].green+src[RIDX(1,dim-1,dim)].green+src[RIDX(0,dim-2,dim)].green+src[RIDX(1,dim-2,dim)].green)>>2;
//the bottom left corner
    dst[RIDX(dim-1,0,dim)].red=(src[RIDX(dim-1,0,dim)].red+src[RIDX(dim-2,0,dim)].red+src[RIDX(dim-1,1,dim)].red+src[RIDX(dim-2,1,dim)].red)>>2;
    dst[RIDX(dim-1,0,dim)].blue=(src[RIDX(dim-1,0,dim)].blue+src[RIDX(dim-2,0,dim)].blue+src[RIDX(dim-1,1,dim)].blue+src[RIDX(dim-2,1,dim)].blue)>>2;
    dst[RIDX(dim-1,0,dim)].green=(src[RIDX(dim-1,0,dim)].green+src[RIDX(dim-2,0,dim)].green+src[RIDX(dim-1,1,dim)].green+src[RIDX(dim-2,1,dim)].green)>>2;
//the bottom right corner
    dst[RIDX(dim-1,dim-1,dim)].red=(src[RIDX(dim-1,dim-1,dim)].red+src[RIDX(dim-1,dim-2,dim)].red+src[RIDX(dim-2,dim-1,dim)].red+src[RIDX(dim-2,dim-2,dim)].red)>>2;
    dst[RIDX(dim-1,dim-1,dim)].blue=(src[RIDX(dim-1,dim-1,dim)].blue+src[RIDX(dim-1,dim-2,dim)].blue+src[RIDX(dim-2,dim-1,dim)].blue+src[RIDX(dim-2,dim-2,dim)].blue)>>2;
    dst[RIDX(dim-1,dim-1,dim)].green=(src[RIDX(dim-1,dim-1,dim)].green+src[RIDX(dim-1,dim-2,dim)].green+src[RIDX(dim-2,dim-1,dim)].green+src[RIDX(dim-2,dim-2,dim)].green)>>2;
    
	//boarder
//left
    for(i=1;i<dim-1;i++){
        dst[RIDX(i,0,dim)].red=(src[RIDX(i,0,dim)].red+src[RIDX(i-1,0,dim)].red+src[RIDX(i-1,1,dim)].red+src[RIDX(i,1,dim)].red+src[RIDX(i+1,0,dim)].red+src[RIDX(i+1,1,dim)].red)/6;
        dst[RIDX(i,0,dim)].blue=(src[RIDX(i,0,dim)].blue+src[RIDX(i-1,0,dim)].blue+src[RIDX(i-1,1,dim)].blue+src[RIDX(i,1,dim)].blue+src[RIDX(i+1,0,dim)].blue+src[RIDX(i+1,1,dim)].blue)/6;
        dst[RIDX(i,0,dim)].green=(src[RIDX(i,0,dim)].green+src[RIDX(i-1,0,dim)].green+src[RIDX(i-1,1,dim)].green+src[RIDX(i,1,dim)].green+src[RIDX(i+1,0,dim)].green+src[RIDX(i+1,1,dim)].green)/6;
    }
//right
    for(i=1;i<dim-1;i++){
        dst[RIDX(i,dim-1,dim)].red=(src[RIDX(i,dim-1,dim)].red+src[RIDX(i-1,dim-1,dim)].red+src[RIDX(i-1,dim-2,dim)].red+src[RIDX(i,dim-2,dim)].red+src[RIDX(i+1,dim-1,dim)].red+src[RIDX(i+1,dim-2,dim)].red)/6;
        dst[RIDX(i,dim-1,dim)].blue=(src[RIDX(i,dim-1,dim)].blue+src[RIDX(i-1,dim-1,dim)].blue+src[RIDX(i-1,dim-2,dim)].blue+src[RIDX(i,dim-2,dim)].blue+src[RIDX(i+1,dim-1,dim)].blue+src[RIDX(i
		+1,dim-2,dim)].blue)/6;
        dst[RIDX(i,dim-1,dim)].green=(src[RIDX(i,dim-1,dim)].green+src[RIDX(i-1,dim-1,dim)].green+src[RIDX(i-1,dim-2,dim)].green+src[RIDX(i,dim-2,dim)].green+src[RIDX(i+1,dim-1,dim)].green+src[RIDX(
		i+1,dim-2,dim)].green)/6;
    }
//up
    for(j=1;j<dim-1;j++){
        dst[RIDX(0,j,dim)].red=(src[RIDX(0,j,dim)].red+src[RIDX(0,j-1,dim)].red+src[RIDX(1,j-1,dim)].red+src[RIDX(1,j,dim)].red+src[RIDX(0,j+1,dim)].red+src[RIDX(1,j+1,dim)].red)/6;
        dst[RIDX(0,j,dim)].blue=(src[RIDX(0,j,dim)].blue+src[RIDX(0,j-1,dim)].blue+src[RIDX(1,j-1,dim)].blue+src[RIDX(1,j,dim)].blue+src[RIDX(0,j+1,dim)].blue+src[RIDX(1,j+1,dim)].blue)/6;
        dst[RIDX(0,j,dim)].green=(src[RIDX(0,j,dim)].green+src[RIDX(0,j-1,dim)].green+src[RIDX(1,j-1,dim)].green+src[RIDX(1,j,dim)].green+src[RIDX(0,j+1,dim)].green+src[RIDX(1,j+1,dim)].green)/6;
    }

//down
    for(j=1;j<dim-1;j++){
        dst[RIDX(dim-1,j,dim)].red=(src[RIDX(dim-1,j,dim)].red+src[RIDX(dim-1,j+1,dim)].red+src[RIDX(dim-1,j-1,dim)].red+src[RIDX(dim-2,j,dim)].red+src[RIDX(dim-2,j+1,dim)].red+src[RIDX(dim-2,j-1,dim)].red)/6;
        dst[RIDX(dim-1,j,dim)].blue=(src[RIDX(dim-1,j,dim)].blue+src[RIDX(dim-1,j+1,dim)].blue+src[RIDX(dim-1,j-1,dim)].blue+src[RIDX(dim-2,j,dim)].blue+src[RIDX(dim-2,j+1,dim)].blue+src[RIDX
		(dim-2,j-1,dim)].blue)/6;
        dst[RIDX(dim-1,j,dim)].green=(src[RIDX(dim-1,j,dim)].green+src[RIDX(dim-1,j+1,dim)].green+src[RIDX(dim-1,j-1,dim)].green+src[RIDX(dim-2,j,dim)].green+src[RIDX(dim-2,j+1,dim)].green+src[RIDX
		(dim-2,j-1,dim)].green)/6;
	}

	//common
	for(i=1;i<dim-1;i++)
		for(j=1;j<dim-1;j++){

			dst[RIDX(i,j,dim)].red=(src[RIDX(i,j,dim)].red+src[RIDX(i+1,j,dim)].red+src[RIDX(i-1,j,dim)].red+src[RIDX(i,j-1,dim)].red+src[RIDX(i+1,j-1,dim)].red+src[RIDX(i-1,j-1,dim)].red+src[RIDX(i,j
			+1,dim)].red+src[RIDX(i+1,j+1,dim)].red+src[RIDX(i-1,j+1,dim)].red)/9;

			dst[RIDX(i,j,dim)].blue=(src[RIDX(i,j,dim)].blue+src[RIDX(i+1,j,dim)].blue+src[RIDX(i-1,j,dim)].blue+src[RIDX(i,j-1,dim)].blue+src[RIDX(i+1,j-1,dim)].blue+src[RIDX(i-1,j-1,dim)].blue+src[RIDX(i,
			j+1,dim)].blue+src[RIDX(i+1,j+1,dim)].blue+src[RIDX(i-1,j+1,dim)].blue)/9;

			dst[RIDX(i,j,dim)].green=(src[RIDX(i,j,dim)].green+src[RIDX(i+1,j,dim)].green+src[RIDX(i-1,j,dim)].green+src[RIDX(i,j-1,dim)].green+src[RIDX(i+1,j-1,dim)].green+src[RIDX(i-1,j-1,dim)].green+src
			[RIDX(i,j+1,dim)].green+src[RIDX(i+1,j+1,dim)].green+src[RIDX(i-1,j+1,dim)].green)/9;

		}


}

我在网上查的时候发现有这么一种说法:

中间的点需要9个点相加求平均值,我们定义三个点,例如图中靠左的三个灰点,我们同时求出三列的像素值之和,按照列进行求和最后将三列值相加取平均的好处在于每两个像素点之间我们只需要多计算一列的值,这可以通过观察图中的灰色区域和黄色区域知晓。

但是没找到代码,我自己照这个思路把上面那段代码中关于中间部分的修改成了以下:

int tr1,tr2,tr3;//定义局部变量,第一列、第二列、第三列的和
int tb1, tb2, tb3;
int tg1, tg2, tg3;
for(i=1;i<dim-1;i++)
{//针对中间部分的最左上角,给定进入循环的初值
tr1=src[RIDX(i-1,0,dim)].red+src[RIDX(i,0,dim)].red+src[RIDX(i+1,0,dim)].red; 
tr2=src[RIDX(i-1,1,dim)].red+src[RIDX(i,1,dim)].red+src[RIDX(i+1,1,dim)].red;

tb1=src[RIDX(i-1,0,dim)].blue+src[RIDX(i,0,dim)].blue+src[RIDX(i+1,0,dim)].blue; 
tb2=src[RIDX(i-1,1,dim)].blue+src[RIDX(i,1,dim)].blue+src[RIDX(i+1,1,dim)].blue;

tg1=src[RIDX(i-1,0,dim)].green+src[RIDX(i,0,dim)].green+src[RIDX(i+1,0,dim)].green;  
tg2=src[RIDX(i-1,1,dim)].green+src[RIDX(i,1,dim)].green+src[RIDX(i+1,1,dim)].green;

	for(j=1;j<dim-1;j++)
	{

	
		 tr3=src[RIDX(i-1,j+1,dim)].red+src[RIDX(i,j+1,dim)].red+src[RIDX(i+1,j+1,dim)].red;
		dst[RIDX(i,j,dim)].red=(tr1+tr2+tr3)/9;//三列的和除以9得到平均值
		tr1=tr2; tr2=tr3;//第二列成为第一列,第三列成为第二列


		 tb3=src[RIDX(i-1,j+1,dim)].blue+src[RIDX(i,j+1,dim)].blue+src[RIDX(i+1,j+1,dim)].blue;
		dst[RIDX(i,j,dim)].blue=(tb1+tb2+tb3)/9;
		tb1=tb2; tb2=tb3;


		 tg3=src[RIDX(i-1,j+1,dim)].green+src[RIDX(i,j+1,dim)].green+src[RIDX(i+1,j+1,dim)].green;
		dst[RIDX(i,j,dim)].green=(tg1+tg2+tg3)/9;
		tg1=tg2; tg2=tg3;

	}
}

但是好像比起之前的版本分数并没有提高,可以看到加法虽然少了几次但是又增加了赋值语句,可能是我写的代码的原因,没有将这个思路的优势充分发挥出来。

参考:

https://blog.csdn.net/qq_42024307/article/details/90210225?utm_source=app

http://xymeow.github.io/post/csapp-lab4/

扫描二维码关注公众号,回复: 10453886 查看本文章
发布了1 篇原创文章 · 获赞 0 · 访问量 10

猜你喜欢

转载自blog.csdn.net/qq_45369312/article/details/105302476