Perflab优化实验
【实验目的】
理解编译器,学习程序优化,从优化程序代码和程序执行速度两方面着手。
【实验原理】 通过循环展开、cache友好、替换变量等手段来实现程序优化。
【实验内容】
将下载下来的kernels.c中的rotate、smooth函数进行优化。
【操作界面】
从网上下载了SSH Secure Shell Client和SSH Secure File Transfer Client代替Putty作为实验平台,可以方便的进行文件上传与下载,所以此次实验以本地编辑文件,再上传覆盖原文件运行为主。软件界面如下:
通过在SSH Secure Shell Client将压缩包解压之后,可以直接通过SSH Secure File Transfer Client下载所需要的kernels.c文件,无需通过cmd输入长指令进行下载。
改好的kernel.c也只需通过SSH Secure File Transfer Client,右击upload即可。
【程序优化】
1. Naive_rotate
1-1.原始代码
char naive_rotate_descr[] = \void naive_rotate(int dim, pixel *src, pixel *dst) {
int i, j;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++) dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)]; }
1-2.分析
这段代码的作用就是将所有的像素进行行列调位、导致整幅图画进行了90度旋转。P从defs.h中可以找到 #define RIDX(i,j,n) ((i)*(n)+(j)) 。
代码从阅读性上来说,这段代码非常具有可读性,但是,从cache友好性来说,这段代码则显得难以接受。所以考虑到cache的大小,应在存储的时候进行32个像素依次存储(列存储)。这样可以做到cache友好、可以大幅度提高效率。
1-3.优化代码
char rotate_descr[] = \void rotate(int dim, pixel *src, pixel *dst) {
int i, j;
int dst_base = (dim-1)*dim; dst += dst_base;
for (i = 0; i < dim; i+=32){ for (j = 0; j < dim; j++){
*dst=*src;src+=dim;dst++; //共31组 *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++;
*dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src+=dim;dst++; *dst=*src;src++; src-=(dim<<5)-dim; //src -= 31*dim dst-=31+dim; }
dst+=dst_base+dim; dst+=32;
src+=(dim<<5)-dim; //src +=31*dim } }
2. Naive_smooth
2-1. 原始代码
void naive_smooth(int dim, pixel *src, pixel *dst){ int i, j;
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
dst[i*dim+j] = avg(dim, i, j, src); } } }
2-2.分析
这段代码频繁地调用avg函数,并且avg函数中也频繁调用initialize_pixel_sum 、accumulate_sum、assign_sum_to_pixel这几个函数,且又含有2层for循环,而我们应该减少函数调用的时间开销。所以,需要改写代码,不调用avg函数。
Smooth函数处理分为4块,一为主体内部,由9点求平均值;二为4个顶点,由4点求平均值;三为四条边界,由6点求平均值。从图片的顶部开始处理,再上边界,顺序处理下来,其中在处理左边界时,for循环处理一行主体部分,于是就有以下优化的代码。
2-3.优化代码
char smooth_descr[] = \void smooth(int dim, pixel *src, pixel *dst) { int i,j; int dim0=dim; int dim1=dim-1; int dim2=dim-2;
pixel *P1, *P2, *P3; pixel *dst1; P1=src; P2=P1+dim0; //左上角像素处理 dst->red=(P1->red+(P1+1)->red+P2->red+(P2+1)->red)>>2; dst->green=(P1->green+(P1+1)->green+P2->green+(P2+1)->green)>>2; dst->blue=(P1->blue+(P1+1)->blue+P2->blue+(P2+1)->blue)>>2; dst++; //上边界处理 for(i=1;i dst->red=(P1->red+(P1+1)->red+(P1+2)->red+P2->red+(P2+1)->red+(P2+2)->red+P3->red+(P3+1)->red+(P3+2)->red)/9; dst->green=(P1->green+(P1+1)->green+(P1+2)->green+P2->green+(P2+1)->green+(P2+2)->green+P3->green+(P3+1)->green+(P3+2)->green)/9; dst->blue=(P1->blue+(P1+1)->blue+(P1+2)->blue+P2->blue+(P2+1)->blue+(P2+2)->blue+P3->blue+(P3+1)->blue+(P3+2)->blue)/9; dst1->red=((P1+3)->red+(P1+1)->red+(P1+2)->red+(P2+3)->red+(P2+1)->red+(P2+2)->red+(P3+3)->red+(P3+1)->red+(P3+2)->red)/9; dst1->green=((P1+3)->green+(P1+1)->green+(P1+2)->green+(P2+3)->green+(P2+1)->green+(P2+2)->green+(P3+3)->green+(P3+1)->green+(P3+2)->green)/9; dst1->blue=((P1+3)->blue+(P1+1)->blue+(P1+2)->blue+(P2+3)->blue+(P2+1)->blue+(P2+2)->blue+(P3+3)->blue+(P3+1)->blue+(P3+2)->blue)/9; dst+=2;dst1+=2; P1+=2;P2+=2;P3+=2; } for(;j dst->red=(P1->red+(P1+1)->red+(P1+2)->red+P2->red+(P2+1)->red+(P2+2)->red+P3->red+(P3+1)->red+(P3+2)->red)/9; dst->green=(P1->green+(P1+1)->green+(P1+2)->green+P2->green+(P2+1)->green+(P2+2)->green+P3->green+(P3+1)->green+(P3+2)->green)/9; dst->blue=(P1->blue+(P1+1)->blue+(P1+2)->blue+P2->blue+(P2+1)->blue+(P2+2)->blue+P3->blue+(P3+1)->blue+(P3+2)->blue)/9; dst++; P1++;P2++;P3++; } //右侧边界处理 dst->red=(P1->red+(P1+1)->red+P2->red+(P2+1)->red+P3->red+(P3+1)->red)/6; dst->green=(P1->green+(P1+1)->green+P2->green+(P2+1)->green+P3->green+(P3+1)->green)/6; dst->blue=(P1->blue+(P1+1)->blue+P2->blue+(P2+1)->blue+P3->blue+(P3+1)->blue)/6; dst++; P1+=2; P2+=2; P3+=2; } //左下角处理 dst->red=(P1->red+(P1+1)->red+P2->red+(P2+1)->red)>>2; dst->green=(P1->green+(P1+1)->green+P2->green+(P2+1)->green)>>2; dst->blue=(P1->blue+(P1+1)->blue+P2->blue+(P2+1)->blue)>>2; 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库perflab实验报告(CSAPP)在线全文阅读。
相关推荐: