此为本人在做实验时所记载的实验日志,仅供参考。
代码一:
void naive_rotate1(int dim,pixel *src,pixel *dst){
int i,j,tmp;//设置一个中间变量tmp,用来存储中间值
for(j=0;j<dim;j++){
tmp=dim-1-j;//由于dim-1-j会经常使用,所以这里进行提前计算,省去了每次计算的时间
for(i=0;i<dim;i++){
dst[RIDX(tmp,i,dim)]=src[RIDX(i,j,dim)];//这里不再对dim-1-j再进行运算
}
}
}
代码一文字描述:
这里是书上的第一个方法,消除循环的低效率。通过观察源代码可以发现在循环中对dim-1-j这个数据进行了重复的调用,所以这里可以对循环进行修改,将计算时的行列进行调换,可以提前计算dim-1-j,这样就可以省去每一次循环中重复计算的时间,可以很好的提高效率。
代码二:
char naive_rotate2_descr[] = "naive_rotate2: Naive baseline implementation";
void naive_rotate2(int dim,pixel *src,pixel *dst){
int i,j,i1,j1;//将程序分成4*4的小块
for(i1=0;i1<dim;i1+=4)
for(j1=0;j1<dim;j1+=4)//这里进行划分
for(i=i1;i<i1+4;i++)
for(j=j1;j<j1+4;j++)//对每一小块进行转换赋值操作
dst[RIDX(dim-1-j,i,dim)]=src[RIDX(i,j,dim)];
}
代码二文字描述:
通过划分成4*4的小方块对整个图进行划分,可以提高空间局部性,但当dim比较小的时候,反而会变慢,因为当dim比较小的时候,决定时间的主要因素是算法复杂度,而分块算法的复杂度比较高。
代码三:
void naive_rotate3(int dim,pixel *src,pixel *dst){
int i, j;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++)
dst[(dim-1-j)*dim+i] = src[i*dim+j];//省去调用函数的时间
}
代码三文字描述:
这是书上的第二个方法,书上说可以通过消除函数调用来提高效率,我看了一下,在循环过程中重复调用了一个RIDX函数,而这个函数的功能就是计算三个参数i,j,n的参数式in+j的数值,所以这里我可以直接将其去掉了,然后在第二个for循环外计算tmpdim的数值,因为这个是重复使用的,然后再在算式中直接计算所需要的数据,而省去了调用函数的时间,但总体上优化不明显
代码四:
void naive_rotate4(int dim, pixel *src, pixel *dst){
int i, j;
for (i = 0; i < dim; i=i+2){//步长调整为2
for (j = 0; j<dim; j=j+2){//步长调整为2
dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];
dst[RIDX(dim-1-j-1, i, dim)] = src[RIDX(i, j+1, dim)];
dst[RIDX(dim-1-j, i+1, dim)] = src[RIDX(i+1, j, dim)];
dst[RIDX(dim-1-j-1, i+1, dim)] = src[RIDX(i+1, j+1, dim)];
}
}
}
代码四文字描述:
这个方法是通过在for循环中尽可能多的进行操作,以此来达到提高效率的目的,这里我只是将步长提高到了2,可以将步长提高到2的倍数,直到32
代码五:
void naive_rotate5(int dim, pixel *src, pixel *dst){
int i,j,tmp1=dim*dim,tmp2=dim *31,tmp3=tmp1-dim,tmp4=tmp1+32,tmp5=dim+31;//定义中间变量
dst+=tmp3;
for(i=0; i< dim; i+=32){
for(j=0;j<dim;j++){//将for循环展开,并通过指针的形式实现对图形的翻转,以32为一个步长
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
dst++;src+=dim;
*dst=*src;
src++;
src-=tmp2;
dst-=tmp5;
}
src+=tmp2;
dst+=tmp4;
}
}
通过循环展开可以进行很强的优化