perlab实验报告(18.0和32.9以上)

perflab实验报告

一.实验目的

理解编译器,学习程序优化,从优化程序代码和执行速度两方面入手

二. 实验内容

kernel.c文件中主要有两个需要进行优化的函数:rotate和smooth,并分别给出了naiverotate和naivesmooth两个函数的基本实现作为baseline作为你改进后的程序的比较对象。你需要读懂rotate和smooth函数,并对其进行优化。你每写一个新版本的优化的rotate和smooth函数,均可在注册后使用driver进行测试,并得到对应的CPE和加速比。

三. 实验分析

3.1 旋转功能分析

源程序
首先我们可以看出dst[RIDX(dim-1-j, i, dim)]在第二个循环中每次都会更新,这对于写的操作
来讲是非常消耗CPE的,并且我们不希望每次循环都会计算一次dim-1-j。综上所诉,我们可以将写的优先级排在读之前,也就是说每次在缓冲区写一行,然后对这一行先进行写的操作,代码如下图所示:

version1
在服务器上我们得到的结果如下图所示,平均加速比为11.6,这对于代码性能提升具有很大影响,说明写的优先级排在读之前是非常正确的,我们接下来也必须要要按照写优先于读的操作进行。

对于矩阵优化我们同样可以结合分块来处理,分块的大小是根据缓冲区的大小而定的,分析得到缓冲区最大长度为32,那么我们将分块的大小设为32,这样保证了既不浪费cache空间又增加了缓存命中率,代码如下:

在这里插入图片描述

运行代码结果如下图,我们得到最终的平均加速比为15.2,这说明分块处理使得代码性能得到了提升,其中原因我认为是因为进行旋转的时候各个像素点之间的映射相互独立,分块后各个块的旋转可以独立进行,减少了关键路径的时间。
在这里插入图片描述

最后我们可以用指针代替数组引用来减少引用内存的时间,因为指针的寻址可以用很小的相对位移就可以得到更替,相比于数组具有更大的优化性能。
在这里插入图片描述

在这里插入图片描述

这段代码运行的性能如下:
在这里插入图片描述

这段代码的思路如下图所示,每次将dst的32行作为一个分块,在一个分块里有若干列,按照循环对每一列进行像素移动,这样就节省了数组寻址的时间。
在这里插入图片描述

3.2 平滑功能分析

对于平滑函数的优化,我们很容易想到需要将平滑分为三个部分:

1、 顶点求平均值;

2、 边上的点(除了顶点)求平均值;

3、 中间的点求平均值。

分为这三个部分的好处在于我们可以不用再通过判断去选择需要求和的区域了,那么我们将代码简单优化如下图所示,在这里我们只分为四条边上的点和中间的点处理,代码性能就提升到了9.3,因此我们可以根据这个思路继续优化。

在这里插入图片描述
如下图所示,红色代表顶点,需要对4个点求平均,那么我们用两个点来求:
在这里插入图片描述

在这里插入图片描述

中间的点需要9个点相加求平均值,我们定义三个点,例如图中靠左的三个灰点,我们同时求出三列的像素值之和,按照列进行求和最后将三列值相加取平均的好处在于每两个像素点之间我们只需要多计算一列的值,这可以通过观察图中的灰色区域和黄色区域,每次计算一列这里又用到了循环展开,基于以上原因,CPE将大幅度提升,当然这里我们也最好使用指针。对于边上的点需要6个点相加求平均值,我们采取的方法与上述相同。

最后得到的性能如下:

在这里插入图片描述

当然,如果我们使用更大的展开,性能会不断提升,使用30*1的展开得到的性能如下图所示,这一性能仍然可以继续提升。
在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值