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) 无缝衔接, 显著降低了部署复杂性, 提升了用户体验与生态适用性.

