csappE3 Chapter5笔记

5.4. 消除循环的低效率

  1. 代码移动:将要执行多次但是计算结果不会改变的计算,移动到到循环外面。


    image.png

5.5. 减少过程的调用

不判断数组边界减少过程调用,对比如下:


image.png

就像stl中vector的成员函数和下标运算符at(),[],at进行范围检查,而[]不进行范围检查。

5.6. 消除不必要的内存引用

消除前:


image.png

消除后:


image.png

由于优化前每次都要读两次内存,写一次内存,减少到读一次内存。主要是减少了读写内存的次数。

小结

对于以上三次优化,达到的效果为:


image.png

原始代码


image.png

消除循环的低效率


image.png

减少过程的调用


image.png

消除不必要的引用
可见消除不必要的引用能够使得优化的效果提升最明显。

5.7.理解现代处理器

image.png

处理器能够达到的最大优化目标


image.png

已经达到的优化与目标值的对比:


image.png

5.8. 循环的展开

循环展开是达到延迟界限的手段:


image.png

循环展开后的效果如下;


image.png

展开次数与CPE的关系:


image.png

进一步优化的瓶颈:

由于连续相乘或者相加等操作需要下次运算使用上一次的结果,使得两个动作必须是顺序化的。这使得处理器无法使用流水线化的功能特性。 造成了最低只能达到延迟的界限。为了突破延迟界限,需要使得连续相乘也能并行化。

5.9. 提高并行性(利用流水线的特性)

5.9.1多个累计变量

类似于cuda中的延迟隐藏特性。使得更多的数据就位,充分利用流水线特性。
为了将相乘解偶,使用多个并联相乘值:


image.png

这使得我们突破了延迟界限:


image.png

继续增加多路并ixng行:


image.png

都几乎达到了吞吐量的界限。

需要展开的数量

此数量与延迟L与容量C有关,即k>=CL。则根据下图:

image.png

取各个的最大值,k需要值为k=CL=5*2=10。从上图可以看出,在等于10时,乘法达到吞吐量界限。

5.9.2.重新结合变换

重新结合变换也是打破了连续相乘的依赖性:


image.png

image.png

关键路径:


image.png

与combine5的对比:


image.png

结果少了一次。

5.9.3 使用向量化的并行:

以上都是标量的修改,使用向量,可以继续提高:


image.png

再次小结

可以总结优化的步骤如下:

  1. 消除循环的效率(1.x倍的提升);
  2. 减少过程的调用(很少的优化);
  3. 消除不必要的内存引用(减少访问内存,多用寄存器)(x倍的优化);
  4. 循环的展开,(1.x倍的优化),使得达到了延迟界限;
  5. 使用流水线的特性(两种方式)达到延迟界限 (x倍的优化);
  6. 使用向量并行;
  7. 注意重新的结合可能影响浮点数的准确性
    可以看出对于优化,最有效的是3、5项的优化,即消除不必要的内存引用与流水线特性提高并行性。

5.11. 一些限制因素

寄存器溢出:
当并行都p超出了可用寄存器数量时,效率反而下降:


image.png

但是一般不会出现,在寄存器溢出之前就达到了吞吐量界限。

--2021.04.04于清明节假期第二天


狗子上天了
狗子上树了

放风筝时狗子风筝上树了,为了救它,我也跟着爬上去了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容