当前位置: 首页 > news >正文

WATaBoy:Game Boy 指令即时编译为 Wasm,性能超原生解释器 1.2 倍!

WATaBoy:将 Game Boy 指令即时编译为 Wasm ,性能超越原生解释器

发布于 2026 年 6 月 28 日

背景

本文假设读者熟悉即时编译的概念。Dolphin 模拟器无法在 iOS 上运行,原因在于 iOS 不支持即时编译,这是 OatmealDome 在博客文章中给出的简要解释。读了那篇文章后,作者一直在思考,要让像 Dolphin 这样依赖 CPU 的模拟器在 iOS 上运行,需要怎么做?难道只能等待几年,等 iPhone 的 CPU 性能足够强大,能通过解释器运行 Dolphin 吗?

不过,苹果对即时编译的限制有一个例外,那就是网页浏览器。JavaScriptCore 在高性能层级会使用即时编译,WebAssembly 也是如此。那么,能否利用这一点,不直接生成本地机器代码,而是生成 Wasm 字节码,最终由网页浏览器编译成本地机器代码呢?阅读了 Andy Wingo 的博客文章后,作者意识到这是可行的。事实上,已经有一些项目采用了这种技术,但截至撰写本文时,还没有游戏主机模拟器使用这种技术,也没有人将其性能与原生运行的解释器进行对比。

因此,作者在本科毕业设计中,决定开发一个 Game Boy 模拟器,先使用解释器,然后使用即时编译为 Wasm 的方式,作为概念验证和基准测试,比较这两种方法的性能。

了解一些模拟器知识的读者可能会不屑一顾,毕竟 Game Boy 模拟器怎么会从即时编译中受益呢?幸运的是,GameRoy 的博客文章详细解释了如何在保持周期准确的同时实现这一点。当然,Game Boy 模拟器从即时编译中获得的好处不如第六代游戏机模拟器那么多,但开发一个 Game Boy 模拟器速度更快,也更符合作者毕业设计的范围。

实现

作者将带你了解 WATaBoy 中最具通用性、且在其他地方找不到指南的部分:在 Rust 中进行 Wasm 代码生成和后期链接。通常,会使用一些工具来生成 Rust 和 JavaScript 之间的粘合代码,但这些工具在处理底层 Wasm 时会带来一些使用上的问题。因此,作者采用了类似于相关文章中描述的方法。

提醒一下,需要使用 Rust 的夜间版,因为稍后会使用一些内联 Wasm 代码。创建一个新的库后,尝试在运行时生成一些执行相同操作的 Wasm 字节码。

Wasm 代码生成

wasm - encoder 库将是唯一的依赖项,借助它可以使用构建器模式来生成 Wasm 指令的字节码。现在,用它来生成一个包含 add 函数的 Wasm 模块的字节码。那么,如何实际执行这些字节码呢?

编译和链接

Wasm 采用的是哈佛架构,不能直接执行程序生成的字节码,必须借助嵌入器(通常是 JavaScript)来编译、实例化并链接新的 Wasm 字节码。假设已经导入了一个名为 linkNewModule 的函数,稍后会在 JavaScript 中实现这个函数。接下来,实现调度函数,以调用间接函数表中的第 n 个函数。将上述内容整合起来,代码如下。最后,需要通过 build.rs 文件向 LLVM 链接器传递两个标志。好了,Rust 部分的工作完成了,构建主 Wasm 模块。

嵌入器(JavaScript)部分

尝试从嵌入器调用 make_and_execute_add 函数,发现控制台输出错误,原来是还没有实现链接函数。现在来实现它,再次运行代码,控制台输出正确结果。这就是 WATaBoy 的代码生成、链接和调度的基础。

结果

比较 WATaBoy 的在 Wasm 中运行的即时编译器、在 Wasm 中运行解释器以及原生运行解释器的性能。在基准测试中,三种模式都被设置为加载游戏的只读存储器,并以无帧率限制的速度模拟循环的标题画面,持续 10 秒的实际时间。测试的三个 ROM 分别是《宝可梦 蓝》《塞尔达传说:林克的觉醒》和《Tobu Tobu Girl》。结果以 10 秒内模拟的总帧数来衡量。

给出了基准测试环境的详情。每个基准测试配置都运行了 5 次,Wasm 基准测试在没有其他标签页打开的网页浏览器中进行,每次运行后都会刷新运行基准测试的标签页。将模拟的总帧数取平均值,然后除以 Game Boy 的刷新率,得到相对速度。

在模拟《宝可梦 蓝》时,即时编译为 Wasm 的方法比原生运行的解释器快约 1.2 倍,也比在 Wasm 中运行的解释器快约 1.5 倍。还在三大主流浏览器引擎上运行了基准测试,看来 Safari 领先了。

基于网页的好处之一是可以直接在博客文章中提供演示,但运行速度太快可能会引发光敏性癫痫患者的癫痫发作,所以在点击开始之前请务必小心。

后续工作

WATaBoy

音频和 Game Boy Color 支持是最明显的缺失功能。在性能方面,模拟图像处理器仍然占据了 WATaBoy 大部分的运行时间,因为还有一些 PPU 中断没有实现预测功能,导致即时编译器比实际需要的更频繁地回退到解释器。

即时编译为 Wasm 的方法明显优于原生运行的解释器,但只是证明了基本块即时编译器优于基本的取指 - 解码 - 执行解释器。解释器已经很快了,并且花了很多时间对其进行优化,但仍然有一些小众的优化技术可能会帮助它赶上基本块即时编译器。优化即时编译器也是如此。作者认为进一步优化后比较它们的相对性能会很有趣,计划将这个项目作为一个爱好继续下去。

即时编译为 Wasm 技术

目前,即时编译为 Wasm 的主要痛点在于代码生成。为了让这种技术得到更广泛的应用,模拟器开发者可能希望有一种方法可以编写人类可读的 WebAssembly 文本格式字符串,并在编译时将其转换为字节码。

这种方法还有另一个局限性,无法实现 Dolphin 依赖的一些底层优化。

结论

这并不一定能证明仅仅通过实现即时编译为 Wasm 的方法,GameCube 模拟器就能全速运行。但鉴于即使是基本块即时编译器也能超越解释器,这是一个值得探索的方向。希望随着代码生成工具的不断成熟,Wasm 能够成为跨平台游戏机模拟器实现更快速度的常用目标,特别是在 iOS 上。

可以使用自己的 ROM 来尝试 WATaBoy 的完整版本。它的主要亮点在于其精妙的实现细节,而非设计。

http://www.gsyq.cn/news/1616331.html

相关文章:

  • 仓储管理的关键点是什么,库存周准确率公式是怎么的?
  • RT-Thread 完全笔记 —— STM32F103 标准库移植与实现
  • 好玩局联合阅彩城打造银川首届汉堡节 滩羊汉堡成为现场人气爆款
  • 杰理之软关机会重启【篇】
  • 闭环智控:利用AI算法动态修正碳带分切偏移与毛刺问题
  • Reflective Prompting:人机对话的镜像工程方法论
  • 工业堆焊未来发展趋势,智能化精密化绿色化成主流
  • conversation-pipeline
  • 65|失败可恢复:断点续跑与任务日志可重放
  • 液冷板年产能50万片:激光产线3条搞定的事,钎焊为什么需要10台炉子
  • Web安全核心漏洞深度解析:从SQL注入到XSS的攻防实战与防御体系构建
  • 如何精准识别区域内的技术研发薄弱环节,提升产业技术补链能力?
  • AI for EDA动态汇总
  • 终极指南:如何为Foobar2000配置三大音乐平台逐字歌词
  • EM3080-W与PIC18F86J50的硬件协同架构与工业条码识别优化
  • STM32F4 外挂QSPI-PSRAM内存随机锁死故障
  • 企业上了ERP系统还要上MES系统吗?
  • 江苏高精度三维扫描仪定制厂家如何选择?ATOS与蔡司方案解析
  • 迅尔涡街流量计解析:适合需宽量程比蒸汽计量的工业用户
  • WebSocket 快速入门教程(附示例源码)
  • MAA明日方舟智能辅助工具:5分钟实现游戏日常全自动化的终极指南
  • STM32F410RB驱动MAX9744的音频系统设计与优化
  • Java面试中高并发与JVM调优的经典问答
  • 零基础小白也能上手:AI建站工具极速操作步骤拆解
  • rust语言学习笔记(指针一)Box<T>(堆分配,独占所有)
  • YOLOv10模型改进-注意力机制-第37篇:YOLOv10改进策略【注意力机制】| ECANet注意力机制
  • ub-dhcp与BIND集成:动态DNS更新的完整实现指南
  • Python LanceDB 超全实战教程(零基础入门到AI向量检索生产级落地)
  • AI科技热点日报 | 2026年07月01日
  • 【边界心法】别用 if 语句防撞!撕碎“软件限位”的逻辑幻觉,论传感器的背叛与“机械死挡块”的绝对物理防线