计组实验报告.doc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告
- 资源描述:
-
课程实验报告 课 程 名 称: 计算机组成与结构 实验项目名称: perflab-handout 专 业 班 级: 计科1403 姓 名: 学 号: 指 导 教 师: 黄丽达 完 成 时 间: 2016 年 5 月 28 日 信息科学与工程学院 实验题目:perflab-handout 实验目得:本次实验得核心任务就是要求修改kernel、c文件,并可以在使用driver进行评测时获得更好得加速比。kernel、c文件中主要有两个需要进行优化得函数:rotate与smooth,并分别给出了naive_rotate与naive_smooth两个函数得基本实现作为baseline作为您改进后得程序得比较对象。本次实验,要求针对每个函数、每个人均至少写出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++) dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)]; } 首先要理解RIDX得意思,在头文件defs、h中宏定义了#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) for (j = 0; j < dim; j++) { dst[RIDX(dim-1-j, i, dim)] =src[RIDX(i,j,dim)]; dst[RIDX(dim-1-j,i+1,dim)] = src[RIDX(i+1,j,dim)]; } for (; i < dim; i++) { dst[RIDX(dim-1-j, i, dim)] =src[RIDX(i,j,dim)]; } } 运行结果截图: 从上述截图可以瞧出,当将循环展开成每次做两个像素点得旋转时,程序得性能明显提高,原来代码得加速比就是1、3,优化后性能就是原始代码得两倍,所以循环展开可以提高程序得性能。 优化2: 循环分块与写优先操作结合可以提高性能,原代码因为循环步长太长,以至于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; i<dim; i+=block) for(j=0; j<dim; j+=block) { //block*block mini matrix im = i+block; for(i1=i; i1<i+block; i1++) { jm = j+block; for(j1=j; j1<j+block; j1++) dst[RIDX(i1, j1, dim)] = src[RIDX(j1, dim-i1-1, dim)]; } } } 从上述截图可以瞧出,当将循环步长分成最大为32,优先dest得写操作时,程序得性能明显提高,原来代码得加速比就是1、3,优化后性能就是原始代码得三倍多,所以循环分块与写优先操作结合可以提高性能。 优化3: 循环展开类循环分块结合,通过减少每次迭代计算元素得数量,减少循环得迭代次数,同时分块可以逐点赋值—>逐行(列)赋值 充分利用块空间,防止前面开辟得块还没有完全利用就被后来得覆盖,提高cache命中率 。 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++; *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次,同时进行类分块时,程序得性能明显提高,原来代码得加速比就是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++) dst[RIDX(i, j, dim)] = avg(dim, i, j, src); } 这段代码得就是把一幅画复制一份赝品,赝品得某点得像素为对应原画得周围像素得平均值(如果该像素点在四个顶点,则赝品得该点像素等于原画包括该点得周围四个点得像素平均,如果该像素点为四条边界上得像素点,则赝品得该点像素点等于原画包括该点得周围六个点得像素平均值,如果该像素点为中间点,则该点像素为原画得周围九个点得平均值)。 分析代码性能不好得因素: 这段代码频繁地调用avg函数,并且avg函数中也频繁调用initialize_pixel_sum 、accumulate_sum、assign_sum_to_pixel这几个函数,且又含有2层for循环,而我们应该减少函数调用得时间开销。所以,需要改写代码,不调用avg函数。 优化1: 不调用avg函数,把avg函数写进smooth函数主体中,通过减少函数调用来达到优化程序得目得。 void smooth(int dim, 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 <=min(j+1, dim-1); jj++) { pixel p=src[RIDX(ii, jj, dim)]; sum、red += (int) p、red; sum、green+= (int) p、green; sum、blue+= (int) p、blue; sum、num++; } } current_pixel、red = (unsigned short)(sum、red/sum、num); current_pixel、green = (unsigned short)(sum、green/sum、num); current_pixel、blue= (unsigned short) (sum、blue/sum、num); dst[RIDX(i, j, dim)] = current_pixel; } } } 从上述运行截图可以瞧出,减少函数调用确实起到了优化代码得作用,但就是优化效果不明显,可能就是编译器在编译得时候做了优化得缘故所以人为得优化性能提升不多,但就是减少函数调用确实可以达到优化代码得效果。 优化2: 对图片进行分块处理,像素点分成图片四个角、图片四条边、图片内部三块分别进行处理。对角而言只需要4个像素点得均值,对于边而言为6个像素点均值,图片内部则需要9个像素点均值。 这样可以减少循环判断得次数,而且原代码得avg函数就是在一次循环中只进行一个像素点得累加,avg函数里用了两重循环,而函数主体有有两重循环,相当于原代码用了四重循环,所以性能很差,所以改进后不使用avg函数,并且通过分块,将每个分块周围得像素点一次性加起来而不就是一个循环累加一个像素点,达到大大减少循环调用得功能。 void smooth(int dim, pixel *src, pixel *dst) { int i,j,lastr,lastb,lastg; int row = dim; int curr; //四个角处理 dst[0]、red=(src[0]、red+src[1]、red+src[dim]、red+src[dim+1]、red)>>2;//用">>"代替"/4"节省时间 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-2]、red+src[dim*2-1]、red)>>2; dst[dim-1]、blue=(src[dim-1]、blue+src[dim-2]、blue+src[dim*2-2]、blue+src[dim*2-1]、blue)>>2; dst[dim-1]、green=(src[dim-1]、green+src[dim-2]、green+src[dim*2-2]、green+src[dim*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[(dim-2)*dim]、green+src[(dim-2)*dim+1]、green)>>2; dst[dim*dim-1]、red=(src[dim*dim-1]、red+src[dim*dim-2]、red+src[(dim-1)*dim-1]、red+src[(dim-1)*dim-2]、red)>>2; dst[dim*dim-1]、blue=(src[dim*dim-1]、blue+src[dim*dim-2]、blue+src[(dim-1)*dim-1]、blue+src[(dim-1)*dim-2]、blue)>>2; dst[dim*dim-1]、green=(src[dim*dim-1]、green+src[dim*dim-2]、green+src[(dim-1)*dim-1]、green+src[(dim-1)*dim-2]、green)>>2; //四条边 for (j=1; j < dim-1; j++) { dst[j]、red=(src[j]、red+src[j-1]、red+src[j+1]、red+src[j+dim]、red+src[j+1+dim]、red+src[j-1+dim]、red)/6; dst[j]、green=(src[j]、green+src[j-1]、green+src[j+1]、green+src[j+dim]、green+src[j+1+dim]、green+src[j-1+dim]、green)/6; dst[j]、blue=(src[j]、blue+src[j-1]、blue+src[j+1]、blue+src[j+dim]、blue+src[j+1+dim]、blue+src[j-1+dim]、blue)/6; } for (j=dim*(dim-1)+1; j < dim*dim-1; j++) { dst[j]、red=(src[j]、red+src[j-1]、red+src[j+1]、red+src[j-dim]、red+src[j+1-dim]、red+src[j-1-dim]、red)/6; dst[j]、green=(src[j]、green+src[j-1]、green+src[j+1]、green+src[j-dim]、green+src[j+1-dim]、green+src[j-1-dim]、green)/6; dst[j]、blue=(src[j]、blue+src[j-1]、blue+src[j+1]、blue+src[j-dim]、blue+src[j+1-dim]、blue+src[j-1-dim]、blue)/6; } for (i=dim; i < dim*(dim-1); i+=dim) { dst[i]、red=(src[i]、red+src[i-dim]、red+src[i+1]、red+src[i+dim]、red+src[i+1+dim]、red+src[i-dim+1]、red)/6; dst[i]、green=(src[i]、green+src[i-dim]、green+src[i+1]、green+src[i+dim]、green+src[i+1+dim]、green+src[i-dim+1]、green)/6; dst[i]、blue=(src[i]、blue+src[i-dim]、blue+src[i+1]、blue+src[i+dim]、blue+src[i+1+dim]、blue+src[i-dim+1]、blue)/6; } for (i=dim+dim-1; i < dim*dim-1; i+=dim) { dst[i]、red=(src[i]、red+src[i-1]、red+src[i-dim]、red+src[i+dim]、red+src[i-dim-1]、red+src[i-1+dim]、red)/6; dst[i]、green=(src[i]、green+src[i-1]、green+src[i-dim]、green+src[i+dim]、green+src[i-dim-1]、green+src[i-1+dim]、green)/6; dst[i]、blue=(src[i]、blue+src[i-1]、blue+src[i-dim]、blue+src[i+dim]、blue+src[i-dim-1]、blue+src[i-1+dim]、blue)/6; } //图片内部 for(i=1;i<dim-1; i++){ lastr=src[row-dim]、red+src[row-dim+1]、red+src[row-dim+2]、red+src[row]、red+src[row+1]、red+src[row+2]、red+src[row+dim]、red+src[row+dim+1]、red+src[row+dim+2]、red; lastb=src[row-dim]、blue+src[row-dim+1]、blue+src[row-dim+2]、blue+src[row]、blue+src[row+1]、blue+src[row+2]、blue+src[row+dim]、blue+src[row+dim+1]、blue+src[row+dim+2]、blue; lastg=src[row-dim]、green+src[row-dim+1]、green+src[row-dim+2]、green+src[row]、green+src[row+1]、green+src[row+2]、green+src[row+dim]、green+src[row+dim+1]、green+src[row+dim+2]、green; dst[row+1]、red=lastr/9; dst[row+1]、blue=lastb/9; dst[row+1]、green=lastg/9; for(j=2;j<dim-1;j++){ curr=row+j; lastr=lastr-src[curr-dim-2]、red+src[curr-dim+1]、red-src[curr-2]、red+src[curr+1]、red-src[curr+dim-2]、red+src[curr+dim+1]、red; lastb=lastb-src[curr-dim-2]、blue+src[curr-dim+1]、blue-src[curr-2]、blue+src[curr+1]、blue-src[curr+dim-2]、blue+src[curr+dim+1]、blue; lastg=lastg-src[curr-dim-2]、green+src[curr-dim+1]、green-src[curr-2]、green+src[curr+1]、green-src[curr+dim-2]、green+src[curr+dim+1]、green; dst[curr]、red=lastr/9; dst[curr]、blue=lastb/9; dst[curr]、green=lastg/9;//内部其她点参考该行前一个点得像素值得到结果 } row+=dim; } } 上述代码之所以使用lastr,lastb , lastg,就是因为像素点得与加起来对于原来得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) { dst[RIDX(i, j, dim)] = avg(dim, i, j, src); dst[RIDX(i, j+1, dim)] = avg(dim, i, j+1, src); } for (; j < dim; j++) dst[RIDX(i, j, dim)] = avg(dim, i, j, src); } 从运行截图上可以瞧出,减少循环次数,将循环展开,尽管跟原代码差别不就是很大,但就是还就是有了一些优化,尽管优化效果不够明显,但就是这个方法就是有效得。 实验结果及分析: 从上述运行结果对比来瞧,每个修改代码或多或少都得到了优化,各种方法得优化程度不一,有些方法优化效果非常显著,有些优化效果很小,但就是每一个修改得代码都达到了优化得目得,所以这次实验室成功得。 实 验成绩展开阅读全文
咨信网温馨提示:1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。




计组实验报告.doc



实名认证













自信AI助手
















微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/4337179.html