Page 121 - 《软件学报》2024年第6期
P. 121
谢汶兵 等: 二进制翻译技术综述 2697
主机实地址的直接代换, 彻底消除软件模拟虚实地址转换引发的性能开销问题.
3.2 原子操作时序维护
原子操作保证了资源访问的互斥性和访问时序. 翻译多节拍原子操作时, 需要维持其原来的时序和语义特性.
然而, 基于软件模拟的指令翻译方式很容易破坏原子操作的原有逻辑时序, 引发正确性问题.
原子操作翻译过程中首先面临的一个挑战是原子指令的等价翻译. 例如 x86 平台有将近 20 条原子指令, 如
inc、xadd 原子操作以及 cmpxchg 比较并交换 (compare and swap, CAS) 指令, 而 MIPS、ARM、Alpha 等平台并
没有 CAS 指令, 其对应的是链接加载 (load linked, LL) 和条件存储 (store conditional, SC) 指令组成的 LL/SC 指令
对. 对于 CAS 原子指令的翻译有两种常用的翻译方法: (1) 将源程序中所有的内存写操作转为原子写, 以保证访问
内存数据的一致性. 但是这种做法对性能影响大. (2) 维持源程序逻辑, 利用 CAS 和 LL/SC 指令对进行功能的等价
模拟. Kristien 等人 [92] 研究发现 QEMU 和 ARCSim [93] 在利用 CAS 模拟 LL/SC 指令时存在正确性问题, 为了保证
从 LL/SC 到 CAS 翻译的正确性, 提出利用软件模拟页翻译缓存更新和失效机制. Natarajan 等人 [94] 提出基于内存
事务解决多线程应用之间的数据竞争问题, 将元数据访问封装在一个事务性原子块内完成, 保证了多线程中锁指
令翻译的正确性和性能. 此外, 基于 CAS 模拟 LL/SC 指令还可能会引发 ABA 问题 [95] . 针对 ABA 问题, Rigo 等人 [96]
[4]
提出利用 Helper 函数软件模拟实现 LL/SC 锁指令翻译. Jiang 等人 [97] 提出无锁队列引用计数的内存保护方法, 只
有内存引用节点计数值为 0 时才允许访问该内存. Cota 等人 [15] 提出通过位图维护 Cache 行和哈希完整地址行检
查来避免数据竞争并保证数据访问的原子性. Zhao 等人 [98] 利用插桩的方式维护一个非阻塞哈希表来记录更新内
存, 保证了锁变量地址与被访问内存地址的一致性.
原子操作翻译过程中还可能会引发锁地址非对齐问题, 例如 x86 平台支持多种地址非对齐的原子操作, 而
MIPS、ARM、Alpha 等平台要求 LL/SC 指令满足 32 位地址对齐. 对于 x86 非对齐指令的翻译通常要求先将访存
地址对齐, 但在不同位宽的原子指令翻译时依旧可能会引发错误. 图 7 是 16 位非对齐指令的访存场景, 假设起始
地址满足 32 位对齐, 其中 (1) 和 (3) 是 16 位地址对齐, (2) 和 (4) 是非 16 位地址对齐. 在该场景下, 用 32 位对齐原
子指令模拟 16 位非对齐原子指令, 此时 (1)(2)(3) 可以被同一个 32 位访存指令访问覆盖, 而 (4) 横跨两个 32 位内
存地址, 翻译可能出错. 针对该问题, Jiang 等人 [97] 利用 LL/SC 指令对模拟 CAS 指令, 采用多内存地址比较交换方
法解决锁地址非对齐可能引发的错误, 但是该方法基于软件模拟 CAS 指令, 可能会引发大量的冗余判断.
(1)
0x***0000 (2)
(3)
(4)
图 7 32 位对齐指令模拟翻译 16 位非对齐指令
3.3 异常和中断处理
代码块执行时遇到异常或者中断, 其需要调用回退机制实现源程序状态的精准还原, 确保逻辑正确. 二进制翻
[3]
译为了实现回退机制, 需要加入额外的保存、恢复机器状态的代码. IA-32 EL 采用还原点检测机制, 一旦发生异
常便从最近的还原点恢复出精确的机器状态. Crusoe 采用硬件支持的影子寄存器保存精确状态. 然而, 回退机制
4
是比较耗时的, 研究表明 IA-32 EL 做一次回退机制需要多达 10 个时钟周期. 此外, 考虑到中断是异步事件.
[9]
QEMU 使用主动处理中断的策略在生成翻译代码阶段插入中断检查代码, 避免回退机制产生的开销. Captive 使
用硬件虚拟化在客户模式下运行一个完整的翻译系统. 它的外部中断通过中断控制器传播到客户机系统, 并在中
断处理程序中设置中断挂起标志. 之后, 在每个翻译块的末尾检查此标志, 如果设置了该标志, 则将其清除并执行
相关的中断处理程序. 但事实上, 与执行翻译块相比, 中断发生的概率要低得多, 翻译器对大多数挂起的中断检查
都是非必要的. Niu 等人 [99] 利用信号和运行时二进制重写技术通知线程何时交付中断, 不再重复检查挂起的中断,