编译过程中的并行性优化(三):软件流水线化与SIMD技术

浙江大学《编译原理》课程报告

上一篇:
编译过程中的并行性优化(二):基本块与全局代码调度算法

软件流水线化

软件流水线化也是一种重要的指令调度技术,就像硬件流水线的指令一样,它通过并行执行来自不同循环体的指令来加快循环程序的执行速度, 在前一个循环体未结束前启动下一个新的循环体,来达成循环体时间上的并行性。相比于简单的展开循环(在提高性能的同时会导致代码的膨胀),软件流水线提供了一个方便的优化方法,能够在优化资源使用的同时保持代码的简洁。

对于循环之间没有数据依赖的 do-all 循环,我们可以用一个简单的对比来说明软件流水线同简单循环展开的不同,下图为简单的循环展开:

在这里插入图片描述

软件流水线化通过将循环展开调度后中重复的部分进行循环,完成流水线。下图为软件流水线化的结果:

在这里插入图片描述

在开始阶段(1-6行)用来填充流水线的指令序列被称为序言;在稳定循环的部分(7-8行)被称为稳定状态;用来排空流水线的指令序列(9-14行)称为尾声

在软件流水中,相邻循环体的启动时间间隔称为启动间距。在软件流水中再次应用循环展开,使同一时刻可以运行多个循环,可以使软件流水实现分数值的启动间距,同时基于展开的优化技术可以降低程序的资源需求和关键路径的长度。但是,循环展开也会引起代码量增长和寄存器需求增大,代码量的增长会导致缓存的性能变差,寄存器需求的增大则有可能使软件流水失败。因此,软件流水的核心问题之一就是展开因子的确定。

对于各个迭代之间的存在数据依赖关系的循环,也称 do-access 循环,软件流水线化也可以起到一定的效果:

在这里插入图片描述

SIMD

SIMD 扩展指令允许将原来需要多次装载的内存中地址连续的数据一次性装载到向量寄存器中,通过一条 SIMD 扩展指令实现对 SIMD 向量寄存器中所有数据元素的并行处理;这种执行方式非常适合于处理计算密集、数据相关性少的音视频解码等多媒体程序。

为了高效利用SIMD扩展部件的特性,需要让编译器分析串行程序中控制流和数据流的特征,识别程序中可以向量执行的部分,将标量语句自动转换为相应的SIMD 向量语句。SIMD 自动向量化编译流程大致可分为3部分,分别是发掘、优化和代码生成:

  • 发掘:识别生成出 SIMD 指令,同时解决控制依赖对发掘的影响。SIMD 扩展部件可在不同的粒度进行识别向量化,包括面向基本块内向量化、面向最内层循环或者循环嵌套的向量化以及面向函数级别的向量化。
  • 优化:首先减小辅助指令的开销,同时考虑数据局部性、寄存器重用等工作。由于部分体系结构的 SIMD 指令只能从内存中存取连续对齐的数据,因此当程序中存在不对齐或不连续内存引用时需要通过移位或者重组等辅助指令才能组成向量。减少辅助指令的数量和提高辅助指令的效率,是增加程序 SIMD 向量化收益的关键问题。
  • 代码生成:考虑平台支持哪些数据类型和向量运算。直接面向特定平台的 SIMD 向量化代码生成存在许多不足,通常分阶段并行编译优化和虚拟向量是解决面向多平台向量化的两个方法。

我的GIS/CS学习笔记:https://github.com/yunwei37/myClassNotes
<一个浙大GIS/CS小白的课程学习笔记 >


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章