Page 8 - 《软件学报》2025年第12期
P. 8

于恒彪 等: 面向编译优化结果不一致的代码高效定位                                                       5389


                 位成功的   14  个测试用例能够获得平均        26.8%  的性能提升.
                    本文第   1  节介绍相关工作, 包括基于高精度浮点差异测试的误差检测、编译优化结果差异性分析和浮点精度
                 修复. 第  2  节介绍本文所需的基础知识, 包括编译优化结果差异性概念和基于浮点精度增强的问题代码二分搜索.
                 第  3  节介绍本文提出的浮点指令差异性引导的             Delta-Debugging  搜索定位方法. 第  4  节通过对比实验展示本文方
                 法的有效性和高效性. 最后总结全文.
                  1   编译优化结果差异性分析相关工作

                    本节详细介绍编译优化结果差异性分析的相关工作, 包括基于高精度浮点差异测试的误差检测、触发编译优
                 化结果差异性的输入生成方法、面向编译优化结果差异性的问题代码定位方法和基于程序变换的浮点精度问题
                 修复技术.
                    (1) 基于高精度浮点差异测试的浮点误差检测. FPDebug            [14] 和  Herbgrind [15] 在实际执行程序每条浮点指令时会
                 同时基于高精度数学库        (MPFR [16] ) 做影子执行, 通过对比影子执行和实际执行结果的差异来评估浮点操作的舍入
                                                    [9]
                 误差; BGRT [17] 、EAGT [18] 、LGSA [19] 和  DEMC 设计了不同的启发式搜索策略在输入域内采样获取触发高浮点误
                 差的输入, FPGen  [20] 将触发浮点误差的输入生成问题转换为程序分支覆盖问题, 并基于符号执行                      [21] 进行求解. 这些
                 方法都会执行搜索得到的输入并与高精度模式下的执行结果进行对比, 依此来评估浮点输入所产生的误差. 与上
                 述方法直接将高精度浮点执行作为测试预言                (test oracle) 不同, FI3D  是根据代码段的高精度版本是否会解决结果
                 不一致性问题来判定该段代码是否是触发编译优化结果差异性的问题来源. 此外, FI3D                         基于编译优化前后浮点指
                 令差异性优先对浮点计算行为改变大的代码段进行精度增强测试, 有效减少了高精度浮点代码变换和执行的开销.
                                                              [5]
                    (2) 触发编译优化结果差异性的输入生成方法. Varity 能够生成随机测试用例, 对随机采样得到的输入对比
                                                                                   [6]
                 不同编译优化选项下的执行结果, 评估该输入是否触发了编译优化结果不一致性; CIV 基于输入空间划分和马尔
                 可夫链蒙特卡洛      (Markov chain Monte Carlo, MCMC) [22]  采样快速产生触发编译优化结果差异性的输入; CIGEN      [23]
                 基于浮点输入域划分和覆盖率引导的输入采样来产生触发编译优化结果不一致性的输入区间. 与这些触发编译优
                 化结果不一致性的输入生成方法不同, FI3D            是对已发现的编译优化结果不一致性进行问题代码定位; Bintuner                 [24]
                 研究编译优化选项对编译生成的二进制指令序列的影响, 并基于遗传算法来产生触发二进制指令序列最大差异性
                 的编译优化配置. 与      Bintuner 关注通过编译优化配置来最大化二进制指令序列差异性不同, FI3D                  关注面向编译优
                 化结果差异性的问题代码定位.
                    (3) 编译优化结果差异性的问题代码段定位. FLiT            [2,3] 通过模糊测试发现触发两个编译优化选项结果不一致的
                 输入, 然后通过对文件和函数的二分搜索来定位导致结果差异性的文件和函数; FLiT                         在搜索过程中观察将给定文
                 件/函数的编译选项恢复成基础编译选项后结果不一致性是否消失来判定问题代码是否在当前文件/函数列表内.
                 显然  FLiT  只能在文件/函数级别定位问题代码, 且不适用于代码文件中包含大量函数或者函数体语句较多的场景;
                      [4]
                 PLiner 是一种基于浮点精度增强的二分搜索定位工具; PLiner 在搜索过程中会将可疑问题代码段自动转换为高
                 精度版本, 然后使用激进编译优化选项编译执行, 如果结果不一致性消失则表示问题代码包含在提升精度的代码
                 中, 会对该段代码进一步进行二分搜索; PLiner 会在函数级、循环级、基本块级和语句级分层进行精化搜索, 适用
                 场景更全面且代码定位粒度更细; PLiner 的二分搜索策略不能有效支持多源问题代码的定位, 且二分搜索的效率
                 不高问题会加重定位过程中高精度浮点运算引入的巨大执行开销; FI3D                     从两个方面对      PLiner 进行提升, 一方面采
                 用  Delta-Debugging  搜索来支持多源问题代码的定位, 另一方面基于编译优化前后的浮点指令差异性来引导搜索,
                                         [7]
                 提升问题代码定位效率; CIEL 是一个面向             GPU  程序编译优化结果差异性的问题代码定位工具, 定位思想与
                 PLiner 基于语句增强的二分搜索类似. 与         CIEL  不同, FI3D  面向传统的  CPU  程序, 且  FI3D  浮点指令差异性指导
                 的  Delta-Debugging  搜索方法可以直接用于优化     CIEL.
                    (4) 基于程序变换的浮点精度修复技术. 程序变换被广泛应用于浮点精度问题修复, 最直接方式是将程序转换
                                        [9]
                 为高精度浮点执行; AutoRNP 会针对给定输入下的浮点误差生成补丁代码, 基于插值技术拟合高精度计算结果;
                 Herbie 为了提升浮点表达式的计算准确性, 会将输入区间划分成不同子区间, 然后在不同输入子区间内使用精度
                      [8]
   3   4   5   6   7   8   9   10   11   12   13