Page 29 - 《软件学报》2025年第9期
P. 29

3940                                                       软件学报  2025  年第  36  卷第  9  期


                 图神经网络    [24] 的调度等. 基于遗传算法的调度使用遗传算法来调整表调度中的启发式规则, 允许算法根据特定输
                 入程序进行动态适应, 从而优化调度效果. 基于进化算法的调度综合考虑代码合并、指令调度和寄存器分配, 根据
                 输出程序和目标硬件配置进行动态启发式调整. 基于图神经网络的调度重点考虑寄存器压力下的指令调度, 训练
                 了一个图神经网络在指令调度过程中降低寄存器压力, 避免寄存器溢出. 同时也有一些工作                             [25−28] 专注于指令调度
                 算法的形式化验证.
                    不同的调度算法各有其适用的场景. 在编译时间敏感的场景下, 多用表调度算法以满足编译时间的限制. 在程
                 序规模不大的情况下, 如果追求对程序指令级并行的极致优化, 则可以使用规划调度. 规划调度的编译时间开销非
                 常高昂, 远非一个产品级编译器所能接受. 当需要综合考虑多个优化目标, 如寄存器分配和指令调度时, 可以运用
                 遗传算法、图神经网络等人工智能的方法来解决. 但是人工智能的方法属于黑盒, 未必能达到全局最优, 且需要收
                 集样本数据提前训练. 另外, 人工智能的方法属于指令集敏感的, 对于新的硬件架构需要重新训练. 与表调度和各
                 种迭代算法相比, 本研究能够确保达到单调度区域内的最优调度. 同时, 本研究可以扩展到复杂的调度算法, 如迭
                 代调度, 图神经网络调度等.
                    为了提高处理器的并行处理能力, 同时简化编译器的优化任务, 出现了一类簇结构                          VLIW  处理器, 该类处理器
                 将多个执行单元划分成若干簇, 一个簇由多个执行单元组成, 每个簇都有自己的指令存储器和数据存储器. 每个簇
                 可以独立地执行一组指令, 并且可以在一个时钟周期内执行多个簇. 编译器只需要将指令打包成簇, 而不需要考虑
                 执行单元级别的细节. 针对簇结构           VLIW  架构的调度算法有二维力量引导算法              [29] 、PCC  算法  [30] 、CAeSaR  算
                 法  [31] . 二维力量引导算法以时钟周期和簇作为二维向量, 采取先分簇后调度的方式, 但仍然存在无法全局考虑簇
                 间相互作用的问题; PCC      算法可以考虑簇间相互作用来提升整体调度效果, 但是                  PCC  算法无法准确找出时间代价
                 函数迅速下降的方向; CAeSaR       算法需要综合考虑调度问题与簇分配和簇间通信问题, 优化求解困难.
                    此外, 部分工作还通过调整指令集和硬件架构来优化指令调度的整体性能, 如谓词执行                             [32] 、硬件循环  [33] 等.
                 添加谓词可以对基本块进行合并, 增大调度空间, 但是会增加编译器中数据流关系的复杂性. 硬件循环通过添加硬
                 件循环指令和控制状态寄存器, 将部分普通循环转化为硬件循环, 减少循环判断和分支转移来提升                                IPC  从而优化
                 调度效果, 但是却增加了编译器生成代码的难度.

                 2.2   RISC-V  指令集、工具链及评测基准
                    RISC-V  指令集具有模块化和易扩展的特点, 按照指令功能的不同划分为多个扩展模块, 包括基础指令集
                 RV32I、乘除指令集扩展       M、浮点运算扩展      F  和  D  等. RV32I (也称基础整数指令集) 是   RISC-V  指令集中最基础
                 的指令集, 它可以单独在核心上运行完整的软件栈. M                在基础指令集上增加了整数乘、除和余数指令. F                和  D  是
                 浮点型扩展, 两者分别增加了单精度和双精度浮点数类型的支持.
                    与现有的    VLIW  架构相比, RISC-V  的  VLIW  具有指令集开源且通用、工具链完善、模块化和易于扩展升级
                 等优点. 例如, 高通    Hexagon  芯片是  VLIW  架构, 是闭源且专用于     DSP  领域的指令集, 不具有通用性, 需要单独为
                 其做编译器后端. RSIC-V     的  VLIW  扩展基于开源    RISC-V  指令集, 具有通用性, 能够复用已有的         RISC-V  相关的
                 软件基础设施, 如编译器中指令选择、后端优化等, 极大降低硬件扩展难度和软件工具链开发难度, 从而降低芯片
                 设计周期和成本.
                    目前主流的     RISC-V  工具链有两个, 分别是     RISC-V-GNU-toolchain [34] 和  LLVM [35] . RISC-V-GNU-toolchain  是
                 由  RISC-V  国际开放组织协作社区维护的项目, 旨在为           RISC-V  处理器提供一套完整的开发环境, 它基于            GNU  工
                 具集, 并针对   RISC-V  指令集进行了优化, 支持多种操作系统平台. 该项目提供了构建、编译和调试                       RISC-V  架构
                 处理器上的软件所需的全套工具, 包括            GCC  编译器、GDB    调试器以及     Binutils 等, 但是  RISC-V-GNU-toolchain
                 本身并无对    VLIW  功能的支持. LLVM    是一个用于构造编译器的基础框架, 编程人员可以利用该基础框架, 构建
                 一个包括编译时、链接时、运行时等功能的编译工具链. LLVM                   对多种后端提供支持, 包括        x86、ARM、RISC-V、
                 Hexagon  等, 且  LLVM  提供了对  VLIW  架构的支持, 如高通的    Hexagon VLIW  后端, 这也为在  LLVM RISC-V  后端
                 增加  VLIW  架构的支持提供了参考.
                    Spike [36] 是  RISC-V  官方提供的一款开源的基于   C/C++开发的   RISC-V ISA  模拟器, 实现了   RISC-V  完整的功
   24   25   26   27   28   29   30   31   32   33   34