Page 130 - 《软件学报》2024年第6期
P. 130
2706 软件学报 2024 年第 35 卷第 6 期
Gedit、GoogleV8、Totem、VisualStudio 等 9 款 x86 典型应用中的向量指令, 发现向量指令在总指令数的平均占
比约为 3.1%. 可见当前应用对向量指令的支持具有普遍性.
由于向量指令自身设计的复杂性, 二进制翻译对向量指令的翻译通常是采用低效的标量指令或者 Helper 函
数模拟实现, 例如 QEMU 和 HQEMU 默认采用低效的 Helper 函数模拟向量指令, 导致翻译效率大打折扣. 文献 [25]
通过重写 Helper 函数和添加向量 TCG IR 来改进 HQEMU 对向量指令的翻译支持, 借助 LLVM IR 对向量指令的
描述支持, 最终在目标平台生成更加高效的向量指令, 测试程序性能加速比可达 2.03 倍. 考虑到一些 SIMD 指令
的语义翻译复杂性, 文献 [11] 优化了文献 [25] 中的方法, 提出混合使用向量 TCG IR 和 Helper 函数向量重写的翻
译方法, 使得 HQEMU 对向量指令的翻译重组更加灵活. 针对结构体存取向量指令翻译效率较低的问题, Fu 等人 [87]
提出基于连续向量访存加重组操作指令的翻译方法, 使用数据重组指令重组结构化数据元素, 实现从源平台到目
标平台的向量指令生成.
针对翻译过程中源平台和目标平台的向量指令位宽不对称问题, Hallou 等人 [166] 完成了 x86 同平台短向量向
长向量的映射, 实现源程序的 SSE 指令到目标程序的 AVX 指令的翻译. Liu 等人 [139] 提出了合并短向量指令来生
成长向量指令的算法, 从而充分利用目标平台并行性并减少寄存器溢出. 然而, 源平台和目标平台对向量指令的位
宽支持存在差异, 二进制翻译在对源程序进行循环控制剥离和向量宽度拓宽时可能会引发地址不对齐问题. 图 9
中 S0–S10 为一段向量指令, 其中 S4–S10 为一段可以向量化的循环指令. 二进制翻译在首次翻译执行 S0–S10 代
码段时, 确定内层 S4–S10 可以向量化. 此时由于 S0–S10 执行时一并执行了内层 S4–S10 循环, 循环指令的内存起
始地址被右移, 本来已经对齐的内存地址可能不再对齐. 文献 [140] 提出动态剥离循环代码, 当内存起始地址满足
长字宽向量指令的对齐要求后再生成长向量指令, 该方法使用投票算法计算剥离计数, 确保尽可能多的长向量对
齐. Hong 等人 [141] 在文献 [140] 的基础上借鉴编译器制导标记方法计算程序内存引用依赖距离, 优化代码剥离过程
中不必要的内存依赖分析.
S0
S1
S2
S3
S4 S4
S5 S5
... ...
S10 S10
图 9 向量翻译优化导致地址不对齐的场景
(2) 标量指令并行化
大量遗留应用程序在最初编译构建时基于标量指令实现, 并未充分利用处理器并行性. 例如, 早期 RISC-V 处
理器没有向量扩展指令支持, 无法向量化程序循环. 当支持向量单元的新 RISC-V 处理器推出时, 原来仅用标量实
现的遗留二进制程序可以通过二进制翻译优化生成支持向量指令的代码. Nakamura 等人 [167] 基于程序控制流和数
据流信息构建依赖关系图, 挖掘指令数据并行性以生成向量指令, 实验表明该方法与编译器自动向量化的优化效
果相近, 但该方法只支持简单数据流向量化. Lin 等人 [168] 利用虚拟寄存器恢复标量循环关键信息, 实现循环内标量
指令向量化, 该方法支持了单出口的内层循环场景向量化. Zhou 等人 [169] 提出基于并行规则提取的指令向量化方
法, 采用动静结合的方法匹配满足翻译规则的代码段, 实现遗留应用程序的并行化. Wu 等人 [135] 对寄存器映射过
程中使用向量寄存器低位的标量指令进行特征分析, 将满足向量化特征的标量指令直接翻译生成向量指令. Jingu
等人 [170] 提出一种基于 LLVM IR 转换的串行程序自动并行优化方法, 提升二进制代码至 LLVM IR, 识别出可并行
代码并插入 OpenMP 接口, 实验表明该方法可以达到与使用源代码并行化同水平的加速效果.
4.3.4 特殊指令优化
跨平台指令集的差异性是限制二进制翻译生成高效目标码的一个关键瓶颈, 对于体系结构差异性较大的特殊