Page 127 - 《软件学报》2024年第6期
P. 127

谢汶兵 等: 二进制翻译技术综述                                                                2703


                    (3) 主从翻译模式
                    一对一翻译模式和一对多翻译模式将源程序的代码翻译与执行过程完全分离, 翻译线程和执行线程无优先级
                 区分, 可能存在线程之间任务请求无法及时响应的问题. 基于主从结构的多线程翻译模式解决了该问题. 主从翻译
                 模式将线程分为主线程和从线程两种类型, 主线程负责常规翻译和目标代码执行, 从线程负责对未翻译的代码进
                 行预测翻译, 执行流程如图        8(c) 所示. 在任务分派时, 首先将待翻译任务加入循环队列, 从线程在队列中领取翻译
                 任务执行预测翻译. 在目标代码执行时发出的翻译请求则由主线程以最快的响应速度直接翻译. 主线程和从线程
                 分别维护各自的代码缓存, 并且主线程可以访问所有从线程的缓存. MT-BTRIMER                     [150] 是典型的主从模式多线程翻
                 译器, MT-BTRIMER  在翻译效率上优于单线程模式, 为二进制翻译器在多线程性能优化方面提供了一个高效灵活
                 的框架.

                 4.2   运行时优化
                    动态优化在程序运行时采集程序的运行信息, 作为进一步优化的依据. 动态优化可以进一步挖掘静态时无法
                 发现的优化机会, 是程序性能优化的一种有效方法. 二进制翻译执行过程涉及分支跳转目标地址计算、缓存代码
                 的确定, 通常是首先从缓冲区代码中进行查找, 如果查找失败则控制流切换到翻译器开展翻译. 此过程涉及频繁的
                 管理、程序状态信息维护等工作, 期间需要频繁的控制流切换和上下文保存恢复, 显著增加了运行时维护开销. 因
                 此, 有必要开展相关优化工作来降低运行时开销.

                 4.2.1    热路径优化
                    对大部分程序而言, 20%       的代码占据了     80%  以上的运行时间     [151] , 充分优化频繁执行的热路径代码可以减少
                 基本块之间的切换和代码块查找开销, 提高程序的整体性能. 其中热路径优化作为一项动态优化技术, 其可以减少
                 基本块之间的切换和代码块查找开销. 运行时采样和代码插桩的方法是现阶段热路径发现的常用手段. 运行时采
                                                                          [2]
                                                                                 [7]
                 样通过   CPU  内置计数器、触发中断或者直接解释执行来完成, 例如                 Aries 、BOA 、Walkabout [47] 、ARCSim [52]
                 和  Rv8 [58] 代码插桩通过在基本块和控制流边缘插入监控代码来识别程序热点, 例如                    IA-32EL 和 [3]  HQEMU [20] 基于
                 此方法.
                    构建更大的代码块区域是热路径优化的一种有效手段, 该方法使得每个基本块执行结束后直接跳入后继基本
                 块继续执行, 减少了寄存器保留恢复与控制流切换次数. 文献                  [152] 借助处理器硬件收集程序执行信息, 并基于有
                 向图构建来表示执行节点或边的频率, 丰富历史分支记录信息以构造高质量区域代码. 代码块的区域构建扩大了
                 代码块区域, 暴露出更多的优化机会. HQEMU           [20] 将热路径代码的基本块组成       Trace 链, 并发送给  LLVM  优化器重
                 新翻译优化, 引入     Trace 链合并后部分课题性能提升了          71%. 文献  [136] 充分延长  Trace 链, 对代码块区域开展删
                 除不常用代码、增加代码局部性、改进传统优化和增加推测等优化. Ispike                     [137] 将执行频率高的基本块组成超级链
                 以提高   Cache 利用率, 并且分离出函数中的热路径代码和冷执行代码, 减少控制流转换开销.
                    多线程中目标程序的代码块信息是线程私有的, 因此在线程共享机制下创建和保存                            Trace 链是具有挑战性的
                 工作. DynamoRIO [43] 为保证线程同步, 当有线程开始创建         Trace 链时会同步设置标志来阻止其他线程重复创建
                 Trace 链, 同时还采用了线程私有的数据结构保存            Trace 链, 在安全点再保存到共享代码缓存中.

                 4.2.2    分支跳转优化
                    分支跳转包括直接分支跳转和间接分支跳转两类. 直接分支跳转的目标地址唯一, 通过程序运行时地址回填
                 等方法即可确定. 间接分支跳转的目标地址在程序执行时确定, 跳转目标地址不唯一. 对于间接分支跳转目标地址


                 控制流切换和翻译查找. 间接分支跳转目标地址的计算是影响二进制翻译效率的关键瓶颈                             [23,27,135] .
                    间接分支跳转目标地址查找是确定源程序跳转地址和目标程序跳转地址关系映射的过程, 查找十分耗时.
                 D’Antras 等人  [138] 基于硬件辅助生成一个包含多      case 目标地址的分支跳转表, 通过目标地址反推理法获取间接
                 分支跳转指令, 引入间接跳转优化后, 可以降低               40%  的运行时维护开销. 对于未涵盖的其余间接分支使用快速
                 原子哈希表处理, 将每个哈希表条目的源和目标地址打包为                    64  位指针并原子的从共享缓存中读写, 避免在分支
                 查询时加入栏栅同步指令, 加速多线程翻译对间接跳转的同步效率. Shen                     等人  [54] 构建  ARM-to-LLVM IR  的地址
   122   123   124   125   126   127   128   129   130   131   132