ImageVerifierCode 换一换
格式:DOCX , 页数:13 ,大小:206.76KB ,
资源ID:9250801      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9250801.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(计组实验4报告.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

计组实验4报告.docx

1、计组实验4报告课程实验报告 课 程 名 称: 计算机组成与结构 实验项目名称: perflab-handout 专 业 班 级: 计科1403 姓 名: 学 号: 指 导 教 师: 黄丽达 完 成 时 间: 2016 年 5 月 28 日信息科学与工程学院实验题目:perflab-handout实验目的:本次实验的核心任务是要求修改kernel.c文件,并可以在使用driver进行评测时获得更好的加速比。kernel.c文件中主要有两个需要进行优化的函数:rotate和smooth,并分别给出了naive_rotate和naive_smooth两个函数的基本实现作为baseline作为你改进后

2、的程序的比较对象。本次实验,要求针对每个函数、每个人均至少写出3种优化版本、并根据driver报告的结果进行性能分析。实验环境:联想ThinkPad E545,Ubuntu14(32位)gdb工具实验内容及操作步骤:rotate原始代码分析:void naive_rotate(int dim, pixel *src, pixel *dst) int i, j; for (i = 0; i dim; i+) for (j = 0; j dim; j+) dstRIDX(dim-1-j, i, dim) = srcRIDX(i, j, dim);首先要理解RIDX的意思,在头文件defs.h中宏定

3、义了#defineRIDX(i,j,n) (i)*(n)+(j),意思是一个n*n的二维数组的第i行,第j列。所以这段代码的是把一幅画进行逆时针方向旋转90该函数将所有的像素进行了行列调位、导致整幅图画进行了逆时针90旋转。分析代码性能不好的因素:原代码由于使用了两重for循环,而且每一重for循环的循环次数为dim次,循环次数过多导致程序的性能非常差,优化方法一是减少循环次数,采用循环展开可以减少循环的次数达到优化效果。优化1:void rotate(int dim, pixel *src, pixel *dst) int i, j; for (i = 0; i dim-1; i=i+2)

4、for (j = 0; j dim; j+) dstRIDX(dim-1-j, i, dim) =srcRIDX(i,j,dim); dstRIDX(dim-1-j,i+1,dim) = srcRIDX(i+1,j,dim); for (; i dim; i+) dstRIDX(dim-1-j, i, dim) =srcRIDX(i,j,dim); 运行结果截图:从上述截图可以看出,当将循环展开成每次做两个像素点的旋转时,程序的性能明显提高,原来代码的加速比是1.3,优化后性能是原始代码的两倍,所以循环展开可以提高程序的性能。优化2:循环分块与写优先操作结合可以提高性能,原代码因为循环步长太长

5、,以至于cache的命中率非常低,所以总体运算效率不高。因此,我考虑到cache的大小,应在存储的时候进行32个像素依次存储(列存储)。(32个像素排列是为了充分利用一级缓存(32KB), 采用分块策略, 每一个块大小为32)这样可以做到cache友好、可以大幅度提高效率,同时写优先操作(写地址连续)比原代码的读优先操作(读地址连续)性能会更好。void rotate(int dim, pixel *src, pixel *dst) int i, j, i1, j1, im, jm; int block=32;/blocking the Matrix for(i=0; idim; i+=blo

6、ck) for(j=0; jdim; j+=block) /block*block mini matrix im = i+block; for(i1=i; i1i+block; i1+) jm = j+block; for(j1=j; j1逐行(列)赋值 充分利用块空间,防止前面开辟的块还没有完全利用就被后来的覆盖,提高cache命中率 。void rotate(int dim, pixel *src, pixel *dst) int i,j; int dst_base=(dim-1)*dim; dst+=dst_base; for(i=0;idim;i+=32) for(j=0;jdim;j

7、+) *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

8、+; *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

9、+; *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-=(dim5)-dim; dst-=31+dim; dst+=dst_base+dim; dst+=32; src+=(dim5)-dim; 从上述截图可以看出,当将循环展开32次,同时进行类分块时,程序

10、的性能明显提高,原来代码的加速比是1.8,优化后性能是原始代码的四倍多,所以循环展开类循环分块结合可以大大提高程序性能。smooth原始代码分析:void naive_smooth(int dim, pixel *src, pixel *dst) int i, j; for (i = 0; i dim; i+) for (j = 0; j dim; j+) dstRIDX(i, j, dim) = avg(dim, i, j, src);这段代码的是把一幅画复制一份赝品,赝品的某点的像素为对应原画的周围像素的平均值(如果该像素点在四个顶点,则赝品的该点像素等于原画包括该点的周围四个点的像素平均

11、,如果该像素点为四条边界上的像素点,则赝品的该点像素点等于原画包括该点的周围六个点的像素平均值,如果该像素点为中间点,则该点像素为原画的周围九个点的平均值)。分析代码性能不好的因素:这段代码频繁地调用avg函数,并且avg函数中也频繁调用initialize_pixel_sum、accumulate_sum、assign_sum_to_pixel这几个函数,且又含有2层for循环,而我们应该减少函数调用的时间开销。所以,需要改写代码,不调用avg函数。优化1:不调用avg函数,把avg函数写进smooth函数主体中,通过减少函数调用来达到优化程序的目的。void smooth(int dim,

12、 pixel *src, pixel *dst) int i, j; for (i = 0; i dim; i+) for (j = 0; j dim; j+) int ii, jj; pixel_sum sum; pixel current_pixel; sum.red= sum.green = sum.blue = 0; sum.num= 0; for(ii= max(i-1, 0); ii = min(i+1, dim-1); ii+) for(jj = max(j-1, 0); jj 2;/用代替/4节省时间 dst0.blue=(src0.blue+src1.blue+srcdim.

13、blue+srcdim+1.blue)2; dst0.green=(src0.green+src1.green+srcdim.green+srcdim+1.green)2; dstdim-1.red=(srcdim-1.red+srcdim-2.red+srcdim*2-2.red+srcdim*2-1.red)2; dstdim-1.blue=(srcdim-1.blue+srcdim-2.blue+srcdim*2-2.blue+srcdim*2-1.blue)2; dstdim-1.green=(srcdim-1.green+srcdim-2.green+srcdim*2-2.green

14、+srcdim*2-1.green)2; dst(dim-1)*dim.red=(src(dim-1)*dim.red+src(dim-1)*dim+1.red+src(dim-2)*dim.red+src(dim-2)*dim+1.red)2; dst(dim-1)*dim.blue=(src(dim-1)*dim.blue+src(dim-1)*dim+1.blue+src(dim-2)*dim.blue+src(dim-2)*dim+1.blue)2;dst(dim-1)*dim.green=(src(dim-1)*dim.green+src(dim-1)*dim+1.green+src

15、(dim-2)*dim.green+src(dim-2)*dim+1.green)2;dstdim*dim-1.red=(srcdim*dim-1.red+srcdim*dim-2.red+src(dim-1)*dim-1.red+src(dim-1)*dim-2.red)2;dstdim*dim-1.blue=(srcdim*dim-1.blue+srcdim*dim-2.blue+src(dim-1)*dim-1.blue+src(dim-1)*dim-2.blue)2;dstdim*dim-1.green=(srcdim*dim-1.green+srcdim*dim-2.green+sr

16、c(dim-1)*dim-1.green+src(dim-1)*dim-2.green)2; /四条边for (j=1; j dim-1; j+) dstj.red=(srcj.red+srcj-1.red+srcj+1.red+srcj+dim.red+srcj+1+dim.red+srcj-1+dim.red)/6; dstj.green=(srcj.green+srcj-1.green+srcj+1.green+srcj+dim.green+srcj+1+dim.green+srcj-1+dim.green)/6; dstj.blue=(srcj.blue+srcj-1.blue+src

17、j+1.blue+srcj+dim.blue+srcj+1+dim.blue+srcj-1+dim.blue)/6; for (j=dim*(dim-1)+1; j dim*dim-1; j+) dstj.red=(srcj.red+srcj-1.red+srcj+1.red+srcj-dim.red+srcj+1-dim.red+srcj-1-dim.red)/6; dstj.green=(srcj.green+srcj-1.green+srcj+1.green+srcj-dim.green+srcj+1-dim.green+srcj-1-dim.green)/6; dstj.blue=(s

18、rcj.blue+srcj-1.blue+srcj+1.blue+srcj-dim.blue+srcj+1-dim.blue+srcj-1-dim.blue)/6; for (i=dim; i dim*(dim-1); i+=dim) dsti.red=(srci.red+srci-dim.red+srci+1.red+srci+dim.red+srci+1+dim.red+srci-dim+1.red)/6; dsti.green=(srci.green+srci-dim.green+srci+1.green+srci+dim.green+srci+1+dim.green+srci-dim+

19、1.green)/6; dsti.blue=(srci.blue+srci-dim.blue+srci+1.blue+srci+dim.blue+srci+1+dim.blue+srci-dim+1.blue)/6; for (i=dim+dim-1; i dim*dim-1; i+=dim) dsti.red=(srci.red+srci-1.red+srci-dim.red+srci+dim.red+srci-dim-1.red+srci-1+dim.red)/6; dsti.green=(srci.green+srci-1.green+srci-dim.green+srci+dim.gr

20、een+srci-dim-1.green+srci-1+dim.green)/6; dsti.blue=(srci.blue+srci-1.blue+srci-dim.blue+srci+dim.blue+srci-dim-1.blue+srci-1+dim.blue)/6; /图片内部 for(i=1;idim-1; i+) lastr=srcrow-dim.red+srcrow-dim+1.red+srcrow-dim+2.red+srcrow.red+srcrow+1.red+srcrow+2.red+srcrow+dim.red+srcrow+dim+1.red+srcrow+dim+

21、2.red; lastb=srcrow-dim.blue+srcrow-dim+1.blue+srcrow-dim+2.blue+srcrow.blue+srcrow+1.blue+srcrow+2.blue+srcrow+dim.blue+srcrow+dim+1.blue+srcrow+dim+2.blue; lastg=srcrow-dim.green+srcrow-dim+1.green+srcrow-dim+2.green+srcrow.green+srcrow+1.green+srcrow+2.green+srcrow+dim.green+srcrow+dim+1.green+sr

22、crow+dim+2.green; dstrow+1.red=lastr/9; dstrow+1.blue=lastb/9; dstrow+1.green=lastg/9; for(j=2;jdim-1;j+) curr=row+j; lastr=lastr-srccurr-dim-2.red+srccurr-dim+1.red-srccurr-2.red+srccurr+1.red-srccurr+dim-2.red+srccurr+dim+1.red; lastb=lastb-srccurr-dim-2.blue+srccurr-dim+1.blue-srccurr-2.blue+srcc

23、urr+1.blue-srccurr+dim-2.blue+srccurr+dim+1.blue; lastg=lastg-srccurr-dim-2.green+srccurr-dim+1.green-srccurr-2.green+srccurr+1.green-srccurr+dim-2.green+srccurr+dim+1.green; dstcurr.red=lastr/9; dstcurr.blue=lastb/9; dstcurr.green=lastg/9;/内部其他点参考该行前一个点的像素值得到结果 row+=dim; 上述代码之所以使用lastr,lastb , last

24、g,是因为像素点的和加起来对于原来的unsigned short类型会发生溢出,所以先定义几个int类型的变量保存像素和结果,将和平均后再赋值给每个像素点。由运行截图可以看出,分块后程序性能大大提高,由原来的加速比为6.8提升到加速比为29.3,优化程度很高。这个方法不但是进行了分块处理,同时也减少了循环的调用,优化结果非常可观。优化3:使用循环展开,减少循环次数达到优化效果。void smooth(int dim, pixel *src, pixel *dst) int i, j; for (i = 0; i dim; i+) for (j = 0; j dim-1; j+=2) dstRI

25、DX(i, j, dim) = avg(dim, i, j, src); dstRIDX(i, j+1, dim) = avg(dim, i, j+1, src); for (; j dim; j+) dstRIDX(i, j, dim) = avg(dim, i, j, src);从运行截图上可以看出,减少循环次数,将循环展开,尽管跟原代码差别不是很大,但是还是有了一些优化,尽管优化效果不够明显,但是这个方法是有效的。实验结果及分析:从上述运行结果对比来看,每个修改代码或多或少都得到了优化,各种方法的优化程度不一,有些方法优化效果非常显著,有些优化效果很小,但是每一个修改的代码都达到了优化的目的,所以这次实验室成功的。实验成绩

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1