本系列文章为中国科学技术大学计算机专业学科基础课《计算机系统》布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第四个实验——性能优化实验(Perflab)。

一、实验名称:perflab

二、实验学时: 3

三、实验内容和目的:

此次实验进行图像处理代码的优化。图像处理提供了许多能够通过优化而得到改良的函数。在此次实验中,我们将考虑两种图像处理操作:roate, 此函数用于将图像逆时针旋转90°;以及smooth,对图像进行“平滑”或者说“模糊”处理。

对于此次实验,我们将认为图像是以一个二维矩阵 M 来表示的,并以 Mi,j 来表记(i,j)位置的像素值。像素值是由红,绿,蓝(RGB)三个值构成的三元组。我们仅考虑方形图像。以 N 来表记图像的行数(同时也是列数)。行和列均以C风格进行编号——从0到 N - 1 。

在这种表示方法之下,rotate 操作可以借由以下两种矩阵操作的结合来简单实现:

  • 转置:对于每个(i,j),交换 Mi,j 与 Mj,i 。
  • 行交换:交换第 i 行与第 N - 1 - i 行。

详情见下图:

        smooth 操作可以通过求每个像素与周围像素(最多是以该像素为中心的3×3的九宫格)的均值。详见图2,像素 M2[1][1] 与 M2[N - 1][N - 1] 由下式给出:

四、实验步骤及结果:

首先将 perflab-handout.tar 拷贝至一个受保护的文件夹,用于完成此次实验。

然后在命令行输入命令:tar xvf perflab-handout.tar 这将使数个文件被解压至当前目录。

你可以进行修改并最终提交的唯一文件是 kernels.c 程序 driver.c 是一个驱动程序,你可以用它来评估你解决方案的性能。使用命令:make driver 来生成驱动代码,并用命令 ./driver 来使其运行。

查看文件 kernels.c,你会发现一个C 结构体:team。你需要将你小组成员的信息填入其中。请马上填写,以防你忘记。

1.naive_rotate

/**naive_rotate - The naive baseline version of rotate*/
char naive_rotate_descr[] ="naive_rotate: Naive baseline implementation";
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)];
}

在头文件defs.h中找到了宏定义:

#defineRIDX(i,j,n) ((i)*(n)+(j))

那么这段代码就很容易为一幅画的旋转,它将将所有的像素进行行列调位、导致整幅图画进行了90度旋转。

但是由于这串代码的步长太长,导致cache的命中率非常低,所以总体运算效率低。因此,我们考虑到cache的大小,应在存储的时候进行32个像素依次存储(列存储)。(32个像素排列是为了充分利用一级缓存(32KB), 采用分块策略, 每一个块大小为32)

这样可以做到cache友好、可以大幅度提高效率。

2.perf_rotate

考虑矩形分块32*1,32路循环展开,并使dest地址连续,以减少存储器写次数

//宏定义一个复制函数,方便程序编写
#define COPY(d,s) *(d)=*(s)
char rotate_descr[] = "rotate: Currentworking version";void rotate( int dim,pixel *src,pixel *dst)
{int i,j;for(i=0;i<dim;i+=32)//32路循环展开,32个像素依次存储for(j=dim-1;j>=0;j-=1)
{       pixel*dptr=dst+RIDX(dim-1-j,i,dim);pixel*sptr=src+RIDX(i,j,dim);
//进行复制操作COPY(dptr,sptr);sptr+=dim;COPY(dptr+1,sptr);sptr+=dim;COPY(dptr+2,sptr);sptr+=dim;COPY(dptr+3,sptr);sptr+=dim;COPY(dptr+4,sptr);sptr+=dim;COPY(dptr+5,sptr);sptr+=dim;COPY(dptr+6,sptr);sptr+=dim;COPY(dptr+7,sptr);sptr+=dim;COPY(dptr+8,sptr);sptr+=dim;COPY(dptr+9,sptr);sptr+=dim;COPY(dptr+10,sptr);sptr+=dim;COPY(dptr+11,sptr);sptr+=dim;COPY(dptr+12,sptr);sptr+=dim;COPY(dptr+13,sptr);sptr+=dim;COPY(dptr+14,sptr);sptr+=dim;COPY(dptr+15,sptr);sptr+=dim;COPY(dptr+16,sptr);sptr+=dim;COPY(dptr+17,sptr);sptr+=dim;COPY(dptr+18,sptr);sptr+=dim;COPY(dptr+19,sptr);sptr+=dim;COPY(dptr+20,sptr);sptr+=dim;COPY(dptr+21,sptr);sptr+=dim;COPY(dptr+22,sptr);sptr+=dim;COPY(dptr+23,sptr);sptr+=dim;COPY(dptr+24,sptr);sptr+=dim;COPY(dptr+25,sptr);sptr+=dim;COPY(dptr+26,sptr);sptr+=dim;COPY(dptr+27,sptr);sptr+=dim;COPY(dptr+28,sptr);sptr+=dim;COPY(dptr+29,sptr);sptr+=dim;COPY(dptr+30,sptr);sptr+=dim;COPY(dptr+31,sptr);
}
}

      3.smooth

char naive_smooth_descr[] ="naive_smooth: Naive baseline implementation";
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函数。

特殊情况,特殊对待:

Smooth函数处理分为4块,一为主体内部,由9点求平均值;二为4个顶点,由4点求平均值;三为四条边界,由6点求平均值。从图片的顶部开始处理,再上边界,顺序处理下来,其中在处理左边界时,for循环处理一行主体部分,于是就有以下优化的代码。

      4.perf_smooth

charsmooth_descr[] = "smooth: Current working version";
void smooth(intdim, 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;//左上角像素处理      采用移位运算代替avg的某些操作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 < dim1; 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 < dim1; 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 < dim2; j += 2) {//同时处理2个像素          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 < dim1; 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 < dim1; 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;
//全部处理完毕
}

      5. 实验结果

 对于rotate操作平均加速了13.1倍

 对于smooth操作平均加速了48.4倍

CSAPP实验四:性能优化实验(Perflab)相关推荐

  1. java实验四结果,java实验四异常处理.doc

    java实验四异常处理.doc 实验四异常处理一.实验目的1.掌握异常的概念和Java异常处理机制.2.掌握异常的定义.抛出和捕捉处理.二.实验内容与要求1.仔细读下面的JAVA语言源程序,自己给出程 ...

  2. 多思计组实验实验四、数据通路实验

    实验四.数据通路实验 一.实验目的: 1.理解总线的概念和作用. 2.连接运算器与存储器,理解计算机的数据通路. 3.理解微命令与微操作的概念. 二.预习要求: 1.读懂实验电路图. 2.在实验之前填 ...

  3. 微控制器实验计算机组成原理,组成原理实验四 微控制器实验

    实验四 微控制器实验 实验四微控制器实验 实验四 一.实验目的 1.掌握时序产生器的组成原理. 微控制器实验 2.掌握微程序控制器的组成原理. 3.掌握微程序的编制.写入,观察微程序的运行.二.实验设 ...

  4. 计算机组成原理学习-实验四 模型机实验(简易版)(详细、人话)

    如果你对其他计算机组成原理知识感兴趣,请考虑阅读我的专栏: 计算机组成原理[专栏] 须知 本文仅作学习笔记使用,仅在CSDN网站发布,如果在其他网站发现,均为侵权行为,请举报.作者:小王在努力. 实验 ...

  5. linux 程序实验总结,Linux实验报告(实验四) shell编程实验

    实验四 shell编程实验(二) 班级:姓名:学号:上机时间:年月日 任课教师:实验教师:实验成绩: 一.实验目的 综合Linux常用命令和vi编辑器的使用,熟练掌握shell脚本编程. 二.实验注意 ...

  6. 计算机网络实验四 VLAN配置实验

    实验四 VLAN配置实验 一.实验目的: 了解华为交换机的基本功能. 掌握虚拟局域网VLAN的相关知识,配置交换机VLAN功能. 掌握VLAN的创建.Access和Trunk接口的配置方法. 掌握用于 ...

  7. mysql安全实验测验答案_实验四∶数据库安全性实验报告.doc

    资源描述 1 / 2实验四:数据库安全性班级:软件工程 0918 姓名:许啸 学号:0911610819[实验目的] :验证数据库安全性[实验要求] :1)新建一个登陆名为 tom,密码为 tom00 ...

  8. java实验四 综合应用实验

    学院 计算机科学与教育软件学院 年级.专业.班 网络16* 姓名 卟咚君 学号 1606100*** 实验课程名称 Java语言实验 成绩 实验项目名称 综合应用实验 指导老师 ** 一.实验目的 熟 ...

  9. 计算机组成原理实验四 微程序控制器实验报告

    我班算是几乎最后一个做实验的班级了,报告参考了一些朋友提供的数据加上一些自己的主观拙见,本人水平有限加之制作仓促难免有错误,望大家批评指正. 4.1 微程序控制器实验 一.实验目的 (1) 掌握微程序 ...

最新文章

  1. 【深度学习笔记】零基础入门深度学习必备知识
  2. 寻找不合群的数据(异常值)
  3. MySQL / 自带的四个数据库介绍
  4. Python 中各种imread函数的区别与联系
  5. 简单的线程同步问题:两个线程交替执行N次【Synchronized、Lock、ArrayBlockingQueue】...
  6. Opencv--resize函数五种插值算法实现
  7. eclipse编译android工程提示无翻译字符串错误的忽略方法
  8. CDN---共享单车算啥,阿里云发布共享网络黑科技PCDN,降低视频行业75%的成本
  9. 解决 Illegal DefaultValue null for parameter type integer 异常
  10. 移远ec20 4g模块linux驱动移植,Hi3798移植4G模块(移远EC20)
  11. java+整合handwrite_解决java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad
  12. 华为手机桌面计算机消失怎么办,华为手机桌面所以图标不见了怎么办
  13. 健身教练教你跑步减肥的正确方法
  14. java打印32位二进制
  15. 电脑选购指南(内含各价位型号最新推选)
  16. Flak 解析json数据不完整?
  17. UnityGUI简介
  18. python求三个数平均值_python求三个数平均值
  19. Scrapy实战:爬取知乎用户信息
  20. 域名备案怎么查 怎样查ICP备案

热门文章

  1. python控制苹果手机触摸屏失灵怎么办_苹果手机触摸屏失灵了,怎么解决?
  2. 2023年会议教学庭审录像机产品分析
  3. excel导出java不完整_有关Java POI导出excel表格中,单元格合并之后显示不全的解决方法。...
  4. 安卓自动滑屏脚本_自动滑屏软件下载-自动滑屏 安卓版v3.1.0-PC6安卓网
  5. SATA硬盘电源线或数据线引发的故障
  6. php计算百分比加成_如何从PHP中的2个值计算百分比变化(增加和减少)
  7. 基于深度学习的时间序列分类[含代码]
  8. 弃全从简 转转的二手手机路好走吗?
  9. python编程怎么画三角形的外接圆_python画出三角形外接圆和内切圆的方法
  10. 顶刊实证复现!排污权交易机制是否提高了企业全要素生产率 ——来自中国上市公司的证据