浅谈QEMU SIMD指令集翻译(genneration)

QEMU SIMD Code Generation


介绍了目前QEMU通过TCG对SIMD指令翻译的方式,以及需要优化的地方

主要参考两篇论文

  • Improving SIMD Code Generation in QEMU(DATE 2015)
  • Effective and retargetable SIMD translation in a dynamic binary translator(Wiley Software: Practice and Experience 2018)

这两篇论文出自同一团队:Institute of Information Science Academia Sinica, Taiwan Province and MOST in Taiwan Province

如有侵权,立即删除

1. SIMD指令发展

  • 现代处理器均支持SIMD指令来提升性能,比如x86架构的MMX,MME和AVX指令集扩展,ARM的NEON指令集扩展

  • **应用程序和编译器对于ARMv7的NEON指令集扩展支持性并不是很好。**比较SPEC2006 fp测试集(使用交叉编译器 arm-linux-gnueabihf-gcc-4.8 编译),很多测试集被编译后几乎不包含NEON指令集,即使是x86的SSE指令集扩展,SPEC2006的SSE指令包含率也不高

    image-20230426135632633

    • 如图,对于ARM架构,GemsFDTD、zeusmp_sfp、GemsFDTD_sfp和
  • **SIMD指令集架构差异很大。**即使是统一架构下,如ARM,不同版本的SIMD指令集的寄存器数量,是否支持双精度浮点运算都不相同;不同架构下的SIMD指令集扩展差异更大,如下表

    image-20230426140206271

2. Challenges in SIMD generation

2.1 SIMD架构自身问题

  • 编译器对SIMD指令支持不完善

    • 主要体现在ARMv7的NEON指令集扩展,此问题已经在ARMv8的NEON指令集扩展得到改善
  • 硬件厂商不断提高SIMD能力,扩展SIMD指令集,使得架构差异很大。包括两类:

    • 相同架构不同版本之间
    • 不同指令集架构之间

    这是DBT不关注SIMD指令翻译的主要原因,版本迭代太频繁

2.2 现代DBT翻译SIMD的问题

以QEMU TCG为例,从两个维度来分析DBT翻译SIMD所面临的问题:

2.2.1 翻译方式

QEMU主要以两种方式翻译指令:IR和Helper Function

  • 一般使用IR来翻译简单的指令,比如访存指令、跳转指令以及Int运算指令等
    • 优点:翻译速度快
    • 缺点:如果IR set太过复杂会影响整体翻译效率,携带信息不能太大
  • 使用Helper Function来翻译复杂指令,如浮点指令和SIMD指令
    • 优点:可扩展性,稳定性高。例如一些硬件结构的缺失,造成两个体系结构指令天然无法翻译执行,使用Helper Function可以解决
    • 缺点:在Call Helper Function之前,QEMU需要将当前CPUState存入Memory中,带来巨大性能开销
2.2.2 翻译结果

image-20230428093600063

QEMU将SIMD指令翻译成线性的标量指令,如一个4组int加法运算指令,QEMU调用4次Helper Function将其翻译成4个host int加法指令,然后由Host cpu执行4次。可见,带来的缺点:

  • 多次Helper Function调用,带来巨大性能开销
  • 将SIMD指令翻译成多个标量指令,并没有充分利用到Host CPU的SIMD处理能力

3. 优化现代DBT翻译SIMD指令方式

介绍上述两篇论文对SIMD指令翻译的优化方式,第二篇论文是对第一篇论文的延续

3.1 Improving SIMD Code Generation in QEMU

目前支持:

  • Guest: ARMv7和IA32
  • Host: x86

这篇论文作者使用两种方式来改进QEMU翻译SIMD指令:Helper Function和Vector IR。由于Helper Function带来的性能开销太大,作者也不再继续讨论,所以我们直接讨论第二种方法

image-20230428093731702

  • Vector IR方式

    • 从字面意思上来看,似乎作者扩展了QEMU的IR set,来专门翻译SIMD指令。虽然这是作者的初衷,但并没有真正扩展IR set

    • TCG IR有两个buffers来优化TCG翻译,一个是存储IR的opcode,一个是存储IR的参数,也就是寄存器号

      在2015年,QEMU TCG并没有采用Guest 寄存器与Host 寄存器映射的方式,而是通过将Guest 寄存器映射到Guest CPUState然后存储在Host Memory里。显然,前者的性能更好。

    • 作者修改了Vector IR的第二个参数Buffer的存储内容,改为存储Guest CPUState和Guest SIMD registers的offset,因此不再需要从register number -> register offset这一步计算,提高了指令翻译性能

通过Buffer改进,不仅对QEMU翻译SIMD指令带来性能提升,同时也提高了对浮点指令的翻译性能,结果如下

image-20230426155734782

从上图看出,有的benchmark加速比相当高,有的几乎没有性能提升,这主要与benchmark的SIMD指令含量和编译器编译出的SIMD指令含量有关系

此外,一个SIMD指令一般最多同时运行4个运算,为什么加速比会超过4呢。这是因为上述方式改进了浮点指令的翻译性能。作者因此关闭了QEMU对浮点指令翻译在此方式上的收益,又测试了一次性能,发现加速比在2.0x-3.0x之间。

  • 不足之处:
    • 仍然是将SIMD指令翻译成一系列多个标量指令,无法利用Host CPU的SIMD处理能力
    • 没有解决SIMD指令更新迭代的问题,例如x86的SSE(128 bit)到AVX(256 bit)转换并没有实现

3.2 Efficient and retargetable SIMD translation in a dynamicbinary translator

目前支持:

  • Guest: ARMv7、ARMv8和IA32
  • Host: x86

image-20230428093651631

结合Helper Function和IR的好处,采用混合的方式

  • 对于较通用的SIMD指令集,采用扩展IR指令集方式
  • 对于复杂的SIMD指令集,采用Helper Function的方式。为了减少Helper Function带来的性能开销,新的Helper Function将采用内联函数的方式

虽然从实验结果来看,此文对SIMD指令翻译性能提升显著,但是作者是在自己改进的一款基于QEMU的模拟器(HQEMU)来实现本文工作的,因此通用性不高

4. 总结

除了上述两篇论文的优化SIMD指令翻译方向外,业界还主要围绕以下两种方向对SIMD指令翻译进行优化:

  • 聚焦于平台。如2.1所述,因为SIMD指令集的通用性很差,很多工作都是点对点开展,比如从x86 SSE指令集(short)到x86 AVX指令集(long)映射
  • 聚焦于寄存器映射。如果Guest寄存器和Host寄存器之间没有映射的话,比如call helper function之前,需要将Guest State保存到memory,并且需要同步,带来性能开销。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值