perflab实验报告.docx

上传人:b****4 文档编号:6850546 上传时间:2023-05-10 格式:DOCX 页数:18 大小:99.01KB
下载 相关 举报
perflab实验报告.docx_第1页
第1页 / 共18页
perflab实验报告.docx_第2页
第2页 / 共18页
perflab实验报告.docx_第3页
第3页 / 共18页
perflab实验报告.docx_第4页
第4页 / 共18页
perflab实验报告.docx_第5页
第5页 / 共18页
perflab实验报告.docx_第6页
第6页 / 共18页
perflab实验报告.docx_第7页
第7页 / 共18页
perflab实验报告.docx_第8页
第8页 / 共18页
perflab实验报告.docx_第9页
第9页 / 共18页
perflab实验报告.docx_第10页
第10页 / 共18页
perflab实验报告.docx_第11页
第11页 / 共18页
perflab实验报告.docx_第12页
第12页 / 共18页
perflab实验报告.docx_第13页
第13页 / 共18页
perflab实验报告.docx_第14页
第14页 / 共18页
perflab实验报告.docx_第15页
第15页 / 共18页
perflab实验报告.docx_第16页
第16页 / 共18页
perflab实验报告.docx_第17页
第17页 / 共18页
perflab实验报告.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

perflab实验报告.docx

《perflab实验报告.docx》由会员分享,可在线阅读,更多相关《perflab实验报告.docx(18页珍藏版)》请在冰点文库上搜索。

perflab实验报告.docx

perflab实验报告

 

 

湖南大学课程实验报告

 

课程名称:

计算机组成与结构

实验项目名称:

perflab

专业班级:

姓名:

学号:

指导教师:

完成时间:

2015年05月22日

 

计算机科学与工程系

实验题目:

程序性能调优实验

实验目的:

kernel.c文件中主要有两个需要进行优化的函数:

rotate和smooth,并分别给出了naive_rotate和naive_smooth两个函数的基本实现作为baseline作为你改进后的程序的比较对象。

你需要读懂rotate和smooth函数,并对其进行优化。

你每写一个新版本的、优化的rotate和smooth函数,均可在成注册后使用driver进行测试,并得到对应的CPE和加速比。

本次实验,要求针对每个函数、每个人均至少写出3种优化版本、并根据driver报告的结果进行性能分析。

实验环境:

Vmware虚拟机ubuntu12.04linux终端

实验步骤和结果分析:

函数源码:

rotate函数:

voidnaive_rotate(intdim,pixel*src,pixel*dst)

{

inti,j;

for(i=0;i

for(j=0;j

dst[RIDX(dim-1-j,i,dim)]=src[RIDX(i,j,dim)];

}

rotate函数的作用是通过将每个像素进行行列调位,将一副点阵图像进行90度旋转。

其中RIDX(i,j,n)即((i)*(n)+(j))。

函数缺点为程序局部性不好,循环次数过多。

可以对其进行分块来提高空间局部性,也可以进行循环展开。

smooth函数:

voidnaive_smooth(intdim,pixel*src,pixel*dst)

{

inti,j;

for(i=0;i

for(j=0;j

dst[RIDX(i,j,dim)]=avg(dim,i,j,src);

}

smooth函数的作用是通过对图像每几点像素求平均值来对图像进行模糊化处理。

函数缺点是循环次数过多和频繁调用avg函数,avg函数中又包含许多函数。

应该减少avg函数的调用次数,且进行循环展开。

第一种版本:

CPE分析:

rotate函数:

voidrotate(intdim,pixel*src,pixel*dst)

{

inti,j,ii,jj;

for(ii=0;ii

for(jj=0;jj

for(i=ii;i

for(j=jj;j

dst[RIDX(dim-1-j,i,dim)]=src[RIDX(i,j,dim)];

}

多添加了两个for函数,将循环分成了4*4的小块,在cache存储体不足够大的情况下,对循环分块能够提升高速缓存命中率,从高提升了空间局部性。

从测试的CPE中也可以看出,在dim是64的时候,原代码和本代码CPE相差不大,而随着dim的增大,本代码CPE增加不大,而原代码CPE急剧增加,就是受到了cache存储的局限性。

smooth函数:

voidsmooth(intdim,pixel*src,pixel*dst)

{

pixel_sumrowsum[530][530];

inti,j,snum;

for(i=0;i

{

rowsum[i][0].red=(src[RIDX(i,0,dim)].red+src[RIDX(i,1,dim)].red);

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

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

rowsum[i][0].num=2;

for(j=1;j

{

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

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

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

rowsum[i][j].num=3;

}

rowsum[i][dim-1].red=(src[RIDX(i,dim-2,dim)].red+src[RIDX(i,dim-1,dim)].red);

rowsum[i][dim-1].blue=(src[RIDX(i,dim-2,dim)].blue+src[RIDX(i,dim-1,dim)].blue);

rowsum[i][dim-1].green=(src[RIDX(i,dim-2,dim)].green+src[RIDX(i,dim-1,dim)].green);

rowsum[i][dim-1].num=2;

}

for(j=0;j

{

snum=rowsum[0][j].num+rowsum[1][j].num;

dst[RIDX(0,j,dim)].red=(unsignedshort)((rowsum[0][j].red+rowsum[1][j].red)/snum);

dst[RIDX(0,j,dim)].blue=(unsignedshort)((rowsum[0][j].blue+rowsum[1][j].blue)/snum);

dst[RIDX(0,j,dim)].green=(unsignedshort)((rowsum[0][j].green+rowsum[1][j].green)/snum);

for(i=1;i

{

snum=rowsum[i-1][j].num+rowsum[i][j].num+rowsum[i+1][j].num;

dst[RIDX(i,j,dim)].red=(unsignedshort)((rowsum[i-1][j].red+rowsum[i][j].red+rowsum[i+1][j].red)/snum);

dst[RIDX(i,j,dim)].blue=(unsignedshort)((rowsum[i-1][j].blue+rowsum[i][j].blue+rowsum[i+1][j].blue)/snum);

dst[RIDX(i,j,dim)].green=(unsignedshort)((rowsum[i-1][j].green+rowsum[i][j].green+rowsum[i+1][j].green)/snum);

}

snum=rowsum[dim-1][j].num+rowsum[dim-2][j].num;

dst[RIDX(dim-1,j,dim)].red=(unsignedshort)((rowsum[dim-2][j].red+rowsum[dim-1][j].red)/snum);

dst[RIDX(dim-1,j,dim)].blue=(unsignedshort)((rowsum[dim-2][j].blue+rowsum[dim-1][j].blue)/snum);

dst[RIDX(dim-1,j,dim)].green=(unsignedshort)((rowsum[dim-2][j].green+rowsum[dim-1][j].green)/snum);

}

}

本函数取消调用了avg函数,通过在函数中直接对像素点的三原色比例分别求平均值的方法来求像素的平均值。

因为取消了avg函数的调用,减少了大多数函数调用环节,并且将重复利用的数据储存在了数组之中,因此提升了速度。

但是本方法提升的速度不够显著。

仅是在dim较小的情况下才有较好的优化。

且当dim>512时,超出了设置的数组大小会报错。

第二种版本:

CPE分析:

rotate函数:

voidrotate(intdim,pixel*src,pixel*dst)

{

inti,j;

inttemp;

intit,jt;

intim,jm;

for(jt=0;jt

{

jm=jt+32;

for(it=0;it

{

im=it+32;

for(j=jt;j

{

temp=dim-1-j;

for(i=it;i

{

dst[RIDX(temp,i,dim)]=src[RIDX(i,j,dim)];

}

}

}

}

return;

}

这个函数跟第一种版本有较大的相似,但是是分成了32*32的小块。

提升的速度比第一种版本多,这是因为32*32的小块充分利用了cache储存,降低了冷不命中率。

如果再增大小块的大小的话,可能因为超出了cache储存,成了和原码同样的情况,降低空间局部性。

smooth函数:

voidsmooth(intdim,pixel*src,pixel*dst)

{

inti,j;

intdim0=dim;

intdim1=dim-1;

intdim2=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)/6;

dst->green=(P1->green+(P1+1)->green+(P1+2)->green+P2->green+(P2+1)->green+(P2+2)->green)/6;

dst->blue=(P1->blue+(P1+1)->blue+(P1+2)->blue+P2->blue+(P2+1)->blue+(P2+2)->blue)/6;

dst++;

P1++;

P2++;

}

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++;

P1=src;

P2=P1+dim0;

P3=P2+dim0;

for(i=1;i

{

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++;

dst1=dst+1;

for(j=1;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;

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;

dst++;

for(i=1;i

{

dst->red=(P1->red+(P1+1)->red+(P1+2)->red+P2->red+(P2+1)->red+(P2+2)->red)/6;

dst->green=(P1->green+(P1+1)->green+(P1+2)->green+P2->green+(P2+1)->green+(P2+2)->green)/6;

dst->blue=(P1->blue+(P1+1)->blue+(P1+2)->blue+P2->blue+(P2+1)->blue+(P2+2)->blue)/6;

dst++;

P1++;

P2++;

}

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;

}

这段代码也是通过不调用avg函数来加速程序。

将Smooth函数处理分为4块,一为主体内部,由9点求平均值;二为4个顶点,由4点求平均值;三为四条边界,由6点求平均值。

从图片的顶部开始处理,再上边界,顺序处理下来,其中在处理左边界时,for循环处理一行主体部分,就是以上的代码。

第三种版本:

CPE分析:

rotate函数:

voidrotate(intdim,pixel*src,pixel*dst)

{

inti,j;

intdst_base=(dim-1)*dim;

dst+=dst_base;

for(i=0;i

{

for(j=0;j

{

*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+=dim;

dst++;

*dst=*src;

src++;

src-=(dim<<5)-dim;

dst-=31+dim;

}

dst+=dst_base+dim;

dst+=32;

src+=(dim<<5)-dim;

}

}

这个函数是通过循环展开来加速程序的。

将循环次数减少32倍,同时处理32个像素点来达成循环展开,因为这32个像素点的处理可以并行处理,因此减少了关键路径的长度,大大加速了程序。

smooth函数:

voidsmooth(intdim,pixel*src,pixel*dst)

{

inti,j,rij;

intrindex=dim;

dst[0].red=(src[0].red+src[1].red+src[dim].red+src[dim+1].red)>>2;

dst[0].blue=(src[0].blue+src[1].blue+src[dim].blue+src[dim+1].blue)>>2;

dst[0].green=(src[0].green+src[1].green+src[dim].green+src[dim+1].green)>>2;

dst[dim-1].red=(src[dim-1].red+src[dim-2].red+src[dim*2-1].red+src[dim*2-2].red)>>2;

dst[dim-1].blue=(src[dim-1].blue+src[dim-2].blue+src[dim*2-1].blue+src[dim*2-2

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2