Page 29 - 《软件学报》2026年第6期
P. 29

2348                                                       软件学报  2026  年第  37  卷第  6  期


                 外一种是结合最终硬件特点, 直接从源码编译.
                    间接函数支持      (indirect function support, IFUNC) 与多库支持  (Multilib) [8,9] 是第  1  种思路的两种具体实现. 每
                 增加一种新的指令集组合或微架构实现, 均需要对软件的源代码进行修改, 这样虽然能提升特定架构上的性能,
                 但也显著增加了维护的开销且降低了方法的泛用性. 例如, 在                    RISC-V  优化  strlen  函数对  glibc 进行的修改中  [10]
                 需要显式提供一个常规实现与一个             Zbb  优化实现, 并通过   hwprobe() 检测是否支持    Zbb, 动态选择优化版本以避
                 免性能退化. 较差的可维护性极大地限制了这类方法的广泛使用. 一般来讲, 这类方法仅应用于少数重点优化的
                 库  (如  glibc), 以及只应用于指令集的几个主要版本         (如  x86-64-v2、x86-64-v3、ARMv9、RISC-V RVA23). 处于
                 这些大版本中间状态的大量指令集组合无法得到支持, 一些没有包含在这些主要版本中的额外指令集扩展也无
                 法得到支持, 并且该类方法无法对每个指令集扩展的启用情况进行细粒度控制, 只能在代码编写时对目标平台
                 做出固定选择, 缺乏编译器或运行器的动态适配能力, 难以针对特定微架构进行更加精细的动态优化                                 [11] . 除此之
                 外, 可以想象随着指令集的持续发展, 为了使用新指令集, 需要持续对这些代码进行修改, 软件的维护负担也将
                 越来越重.
                    类似  Gentoo  的源代码发行版是第      2  种思路的实现. Gentoo  以源代码而非二进制进行分发, 进而在终端用户侧
                 进行源代码向二进制的编译. 该方案可以结合最终硬件平台特性充分发挥编译器的优化潜能, 但存在两类问题: 一
                 是要求用户具备处理各种复杂编译问题的能力, 如编译依赖的缺失、版本兼容问题等; 二是在源码编译时不仅耗
                 费大量硬件资源      (包括  CPU、内存), 还需要从网络上下载编译依赖, 导致总体耗时较长, 例如, 在                  openEuler 24.03
                 LTS SP2  平台上针对  RISC-V64  架构构建  OpenCV  软件包的完整过程耗时长达         15 h [12] .
                    为此本文提出构建操作系统发行版的一种思路, 即将从源代码直接编译生成二进制操作系统的主流方式, 转
                 化为结合编译过程环境依赖差异的两阶段构建流程. 第                   1  阶段, 从源代码编译到一种中间表示, 例如            LLVM IR
                 (LLVM intermediate representation), 此过程需要处理复杂的依赖关系, 例如编译器版本、头文件、本地环境变量、
                 同软件包中各文件之间的关系等, 环境的变化可能会造成编译结果的变化, 乃至编译失败, 同时这一阶段所需要时
                 间也是整个编译过程中最长的; 这一阶段可以由专业的操作系统开发团队                        (如  openEuler 开发团队) 在云环境中进
                 行. 第  2  阶段, 从中间表示生成最后的可执行程序或共享库等, 既可以生成兼容性最好的可执行程序, 也可以根据
                 具体的硬件指令集和微架构实现进行定向优化, 此过程可以在无需编译依赖的环境进行, 且资源消耗较少, 在最终
                 用户设备上进行. 通过实现以上方案, 既能够摆脱源码编译对于最终用户技能的高要求, 同时也能够生成满足兼容
                 性要求的可执行程序或共享库, 使硬件性能的发挥接近从源码编译的效果.
                    LLVM  以及  Clang  编译器支持持久化存储的中间表示          (LLVM IR), 随着  LLVM IR  的逐渐标准化和逐渐稳定,
                 其为解决这个问题带来了希望. 但是大部分现有软件使用的构建系统                       (如  Autotools 和  CMake) 均是按照文件为单
                 位, 首先将  C  源码编译成目标机器的目标格式           (如  Linux  系统上的  ELF  格式), 再将这些单独的目标文件链接成为
                 一个可执行程序或动态库. 这与我们提到的两个阶段方法完全不同, 因此需要一种创新性的方案在不需要修改现
                 有软件代码及构建系统的基础上使用新的方式构建和分发软件.
                    针对上述背景与挑战, 本文提出了一种软件构建与分发工具链                     RuyiBuild. RuyiBuild  工具链以统一的  LLVM
                 IR  文件作为跨平台软件分发的中间表示格式, 其可以转换为任意扩展指令集组合和微架构优化的二进制代码, 这
                 样既避免了用户从源码进行构建, 也避免了按              Multilib  要求修改软件的构建系统, 更无需如        IFUNC  般对  C  代码进
                 行修改, 并且具备了      Multilib  和  IFUNC  所不具备的细粒度架构和微架构支持. 此外, RuyiBuild      工具链提出一种基
                 于动态模板的、面向        RISC-V  指令集多样性的兼容性感知多层级构建方法, 能够针对目标设备的具体指令集扩展
                 组合与微架构特征进行动态检测与精细化优化, 极大提高了软件在不同设备上的实际性能表现.
                    如表  1  所示, RuyiBuild  工具链通过封装程序两次调用       clang、install 等工具, 从而实现无需修改目标软件源码
                 或构建系统, 保持了软件生态的完整性与稳定性; 通过第                 1  次调用, 构建满足最低兼容性要求的二进制代码以满足
                 对兼容性的要求; 通过第       2  次调用, 构建满足最优性能的        LLVM IR, 继而结合目标平台的指令集和微架构特性, 实
                 现贴近硬件特性的细粒度动态转换与精确优化; 此外, RuyiBuild                工具链与主流      Linux  发行版软件管理工具      (如
                 rpm、dnf) 无缝衔接, 显著降低了部署复杂性, 提升了用户体验与生态适用性.
   24   25   26   27   28   29   30   31   32   33   34