探索 WebAssembly 优化器中遗漏的优化功能

2023-10-12 16:04:28 浏览数 (2)

本文翻译自软工A类会议ISSTA 2023的 Exploring Missed Optimizations in WebAssembly Optimizers

摘要

将复杂的应用程序部署到网络浏览器的蓬勃趋势推动了 WebAssembly(wasm)编译工具链的发展。用不同高级编程语言编写的软件被编译成 wasm 可执行文件,可在虚拟机中快速安全地执行。wasm 可执行文件的性能在很大程度上取决于编译器的优化。尽管wasm可执行文件的使用非常广泛,但最近的研究表明,现实世界中wasm应用程序的运行速度比预期的要慢,这表明wasm优化存在缺陷。

本文旨在首次系统、深入地了解 wasm 优化的现状。为此,我们提出了 Ditwo,这是一个差异测试框架,用于发现 wasm 优化器的优化遗漏(MO)。Ditwo 将 C 程序编译成本地 x86 可执行文件和 wasm 可执行文件,并对运行每个可执行文件时记录的优化指示跟踪(OITrace)进行区分,以发现遗漏优化(MO)。每个 OITrace 都由全局变量写入和函数调用组成,这两个性能指标能切实、系统地反映 wasm 和本地可执行文件的优化程度。我们对官方 wasm 优化器 wasm-opt 的分析成功识别出 1,293 个触发 wasm-opt MO 的输入。通过大量人工操作,我们找出了所有 MO 的 9 个根本原因,并估计修复发现的 MO 至少可以提高 17.15%的性能。我们还从研究结果中总结了四条经验,以提供更好的 wasm 优化。

正文

WebAssembly (wasm) 是一种日益重要的low-level网络语言,有多种源语言可编译为它。从 "无服务器 "云计算到智能合约平台,再到本地应用程序中的沙箱库,甚至作为独立的 wasm 运行时执行的通用字节码,浏览器都广泛支持它,各种网络应用程序也都在使用它。

wasm社区提供了wasm编译器,用于将C/C 、Rust和Go等流行的高级语言转换为wasm可执行文件。此外,官方的 wasm 编译器基础库 Binaryen,也为开发 wasm 编译器提供了便利。Binaryen 的核心组件 wasm-opt,包括经典的编译时优化和wasm特定优化,以有效改善 wasm 代码的大小和速度。目的是 "使 Binaryen 强大到足以单独作为编译器后端使用"。迄今为止,许多工业级的 wasm 编译器都采用了 wasm-opt 。

从整体上看,浏览器供应商推广wism的目的是加快网络应用的速度,并取代数十年来主导客户端脚本的JavaScript(JS)。由于在开发wism生态系统方面投入了大量资源,业界普遍期望wism能达到与本地代码相媲美的性能。然而,最近的研究表明,wasm 程序的运行速度可能是本地代码的两倍。研究还发现,wasm 在速度和内存使用方面可能不会明显优于 JS。

以往的研究通常将 wasm 性能不足(与直觉相反)归咎于编译时(和运行时)优化不力。然而,对优化不足的 wasm 代码的系统性描述仍然缺失,更不用说对 wasm 优化器的根本原因进行探索和分类了。因此,本文旨在对wasm优化器的优化遗漏(MO)进行全面深入的研究。虽然通过阅读wasm优化器的文档和代码可以部分实现这一目标,但在实践中,其可行性受到wasm优化器的复杂性和程序优化性质的限制:优化机会可能是微妙的,只有在处理编译器前端发出的特定代码时,某些优化才会被视为 "错过"。

原则上,要决定 wasm 优化器的 MO,需要一个 "基本事实"(例如,手工制作一些经过完全优化的 wasm 可执行文件)与之进行比较,而这很难获得。受当代 C 编译器优化测试研究的启发,我们转而探索一种差异测试设置,将现代 C 编译器完全优化过的本地 x86 可执行文件视为 作为揭示 MO 的 "参考"。这就实现了自动化、系统化 和可扩展的 Wasm 优化器测试。总之,我们提出了 Ditwo、 一个针对 wasm 优化器的差异化测试框架。Ditwo 可区分 wasm 二进制代码的运行时行为和其本地 x86 对应代码的运行时行为进行区分,以发现 MO。

关键的技术难题在于如何从 wasm 运行日志中选择适当的 "性能指标",并对其进行实际可行的比较,以发现各种被忽视的 wasm 优化机会。为此,Ditwo 启动了 wasm 和本地可执行文件,以记录两个指标:全局变量写入和函数调用。这些日志形成了一对优化指示跟踪(OITraces),用于交叉比较。根据我们的观察,全局变量写入和函数调用在 wasm 和 x86 可执行文件中具有弹性,也就是说,无论两个可执行文件的差异如何,它们都大致接近。此外,这些指标还受到两种编译流水线中大量优化过程的影响。因此,通过区分 OITraces,我们将 wasm 优化与成熟的 C 编译器优化进行了比较;交叉比较中暴露出的不一致表明错过了 wasm 优化的机会。

Ditwo 用于测试 wasm-opt,它是由 wasm 社区维护的主流优化器,被大多数 wasm 编译器广泛使用。因此,在 wasm-opt 中发现的 MO 会妨碍在各种平台上提供快速、可移植的 wasm 应用程序。使用 16K 随机生成的 C 程序作为测试输入,Ditwo 发现了 1293 个导致 wasm 程序优化不足的输入。我们用了大约 140 个工时,手动诊断出了所有暴露的 MO 背后的根本原因。此外,通过对五个真实世界应用程序的半人工研究,我们估算出了修复 MO 案例后性能提升的下限,平均为 17.15%。这些结果表明了 Ditwo 发现的 MO 的严重性。我们进一步总结了四条经验,以更好地优化 wasm 代码。

0 人点赞