Page 126 - 《软件学报》2024年第6期
P. 126
2702 软件学报 2024 年第 35 卷第 6 期
和性能优化开销大的难题. Hu 等人 [10] 基于动态翻译基本块并采样分析热点函数, 对发现的热点函数调用超级块优
化器进行离线优化. 类似地, MTCrossBit [36] 将代码优化工作与翻译工作剥离, 在首次动态翻译时额外插入探测指令
收集程序的运行时信息, 之后根据收集到的信息指导静态翻译完成离线优化. 为进一步减少运行时收集信息带来
的开销, Guan 等人 [55] 在 MTCrossBit 的基础上, 提出只收集跟踪执行路径上相邻边的执行信息, 大幅降低了执行信
息的数据规模. 此外, Wang 等人 [147] 提出对代码进行静态预翻译并完成深入优化, 将优化后的代码以动态库的形式
提供给动态翻译调用. 动态翻译主要负责程序内存空间映射、程序状态更新以及共享库调用执行等任务. LLPEMU [34]
采用了与文献 [147] 类似的方法, 引入多面体优化技术对静态翻译发现的程序循环体进行深度优化并提供给动态
翻译调用.
4.1.2 多线程翻译优化
动静结合的优化方法有效降低了代码翻译和优化开销, 但是其对于处理器的多核资源利用还不够. 为此, 有研
究利用多线程技术优化翻译开销. 传统的二进制翻译系统采用单线程模式: 串行处理代码翻译和代码执行任务, 导
致大量资源互相等待, 处理器资源利用率低下. 为了解决该问题, 一些研究工作提出充分利用多核处理器体系结构
的并行优势, 将翻译和执行任务划分到不同线程, 尽可能地隐藏翻译过程带来的开销. 多线程翻译在任务划分上可
以分为一对一翻译、一对多翻译以及主从翻译 3 种模式.
(1) 一对一翻译模式
一对一翻译模式包含一个执行线程和一个翻译线程, 翻译线程和执行线程的并行化保证了在代码执行时可以
同步进行代码翻译, 如图 8(a) 所示. 翻译线程负责对源程序进行翻译, 包括常规翻译和预测翻译. 常规翻译负责对
执行过程中未被翻译的源程序进行翻译, 预测翻译则对可能被执行的目标代码进行预测翻译. 执行线程负责执行
翻译后的目标代码. 相比于单线程翻译, 一对一的多线程翻译模式提高了二进制翻译的并行度, 但是也存在一些缺
陷: 当执行线程提出翻译请求时, 预测翻译无法同时进行, 此时就退化成了单线程模式. 此外, 单个基本块的翻译时
间可能比执行时间长, 当翻译线程处于预测翻译时, 执行线程发出的新的翻译请求无法被及时响应, 严重影响整体
翻译效率. 多线程 Strata [22] 采用了一对一翻译模式.
(2) 一对多翻译模式
相比一对一翻译模式, 一对多翻译模式支持动态扩充翻译线程数量 [20] , 如图 8(b) 所示. 为了充分提升线程的
并行处理能力, Ma 等人 [148] 提出创建翻译线程、超级块线程、性能剖析线程以及执行线程的多线程翻译系统, 通
过高效的利用多核资源提升系统的整体性能. HQEMU [20] 将 QEMU TCG 翻译器和 LLVM 优化器分别运行在不同
线程上, 根据优化任务量动态的调整优化器线程数量. Liu 等人 [149] 基于离线采样策略构建 CFG 实现预测翻译, 以
流水线的方式运行前端到 IR 提升、IR 到后端翻译和代码执行. Engelke 等人 [38] 构建了客户端+服务端的多进程翻
译框架, 根据任务需求创建多线程, 有效地解决了翻译请求无法及时响应的问题. 类似地, ExaGear [12] 采用了两级翻
译模式, 一级进程负责快速翻译, 二级优化进程则对热点代码进行深层次并行优化, 最终将优化后代码重新注入到
代码池供后续程序执行使用. 一对多翻译模式解决了一对一翻译模式并发度低和响应翻译请求不及时的缺陷, 可
以在同一时间响应多个翻译任务. 但是当所有线程均在执行预测翻译时, 一对多翻译模式也面临着无法及时响应
执行线程发出的翻译请求的可能性.
执行线程 翻译 翻译线程 执行线程 翻译 翻译线程 主线程 从线程
请求 请求
目标代码 目标代码 源程序 目标代 翻译 源程序
执行 源程序 执行 码执行 请求
翻译线程 1 翻译线程 N 常规 从线程 1 从线程 N
常规翻译 翻译
常规翻译 ... 常规翻译 预测翻译 ... 预测翻译
代码缓存 预测翻译 代码缓存 主线程代码缓存
预测翻译 预测翻译
从线程代码缓存
(a) 一对一翻译模式 (b) 一对多翻译模式 (c) 主从翻译模式
数据流 控制流
图 8 二进制翻译中多线程翻译模式