一个半月前写了关于 RISC-V DynaRec(Box64 的 JIT 后端)的最新状态及在 RISC-V 上运行《巫师 3》的可喜进展,若没看过不要错过。
- x86 指令集多年来缓慢扩展了大量 SIMD 指令,几乎所有 x86 程序现在或多或少会使用 SIMD 指令,box64 需高效翻译这些指令。
- 几乎所有指令集都有 SIMD 或向量扩展,如 AArch64 的 Neon、SVE 等,RISC-V 有向量扩展(RVV),它们目标相同,多数基本指令相同可一对一翻译。
关于 box64 对 x86 SIMD 指令的支持:
- 最完整的 AArch64 DynaRec 支持从 MMX 到 AVX-2 的几乎所有指令,用 Neon 指令翻译;最不完整的 LoongArch64 DynaRec 只支持一小部分 MMX 和 SSE*指令,未实现的操作码会回退到解释器,速度很慢。
- 一个半月前 RISC-V DynaRec 用标量指令模拟 MMX 到 SSE4 的大多数指令,如 SSE2 的
paddq
opcode 用两个LOAD LOAD ADD STORE
序列共 8 条指令模拟,而 AArch64 则一对一翻译为VADD
指令。 - RISC-V 指令集多样性大,不同硬件对 RVV 的支持不同,JH7110 没有向量扩展,SpacemiT K1/M1 支持 RVV 1.0 向量寄存器宽度 256 位,SG2042 支持旧的 RVV 版本 0.7.1(或 XTheadVector)寄存器宽度 128 位,所以不能假设 RVV 总是存在,用标量实现作为回退是合理必要的。
- 过去一个月为 RISC-V 后端添加了初步的 RVV 和 XTheadVector 支持,且大部分代码可共享,如
paddq
opcode 现在用VSETIVLI
和VADD.VV
实现,通过添加 SEW 跟踪机制只在必要时插入vsetivli
。 - 目前已在 RVV / XTheadVector 中实现了足够多的 x86 SIMD 指令进行基准测试,以 dav1d AV1 解码基准为例,在有 XTheadVector 扩展的 MilkV Pioneer 上比标量版本快近 4 倍,比原生快(原生 dav1d 不支持 XTheadVector)。
关于 RISC-V 缺少位范围插入和提取指令的问题:
- [camel-cdr]提出用 4 条指令实现
ADD AH, BL
,核心思想是将实际加法移到高位以消除进位影响,box64 采用此方法作为快速路径。 - XTheadBb 扩展中的
TH.EXTU
指令可用于位提取操作,如在间接跳表查找中,使用TH.ADDSL
和TH.EXTU
可减少指令数量使代码更易读。 - 测试 7z b、dav1d 和 coremark ,有或没有 XTheadBb 分数无明显差异,但微优化会累积产生可测量的性能增益。
- [camel-cdr]提出用 4 条指令实现
- 结尾:这只是优化 RISC-V DynaRec 的开始,接下来会添加更多 SSE、MMX 和 AVX 指令,让 RISC-V DynaRec 像 AArch64 一样出色,期待游戏方面的进展。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。