QEMU资源占用过高的问题

QEMU是一个非常流行的虚拟机软件,支持多种架构CPU的模拟运行,就连我常常使用的VPS实际很多都是QEMU实现的。除了x86架构之外,QEMU支持各种常见的处理器模型,比如ARM,MIPS,PowerPC,RISCV等等,这个也是QEMU区别于其他虚拟机软件的优势之一。

最近在学习ARM的时候,因为懒得搞什么开发板,所以就直接在QEMU上搞一下,QEMU还是非常方便的,直接下载ARM相关组件之后就可以支持一些ARM的开发板,也就是说开发板上比如串口之类的外设也是可以直接支持的。不过因为是模拟方式支持,所以串口并没有什么波特率一说,直接就是写寄存器输出,没那么多事,感觉也不错。

目前在QEMU虚拟的ARM开发板上,我已经跑通了串口的输出(输入还是有点问题),中断什么的也可以正常产生了,剩下的就是还要看看和TrustZone相关的东西可不可以支持了。不过这是后话了,今天我们还是要来看看我们的主题,QEMU资源占用过高的问题。

现象分析

在使用QEMU仿真ARM软件的时候,可以直接load elf到QEMU相应的内存地址,这样我们的镜像可以正常启动了,但是运行过程中我发现QEMU对于宿主PC CPU资源占用基本一只维持在100%,长此以往,很容易将我的苹果烤熟的。通过分析,我们知道,一般我们在写程序的时候,当程序执行完成的时候一般会进入一个while(1),这个时候QEMU并不知道仿真运行已经结束,而是仍然会将循环指令作为一个普通指令执行,这样在没有资源限制的情况下,CPU的占用确实也会达到最高。

解决方法

既然知道了问题的原因,那么问题的结果也就比较简单了,现在我能想到以下几种不同的方法:

  1. 程序运行结束之后,直接退出QEMU仿真,但是QEMU似乎并没有提供这个接口。
  2. 将CPU主频降低,不过这个似乎也不可行,毕竟仿真的时候好像并不会在意这个仿真频率。
  3. 直接进入低功耗模式,这个是一个可行并且验证过的方案,并且仿真运行的时候也没有那么多乱七八糟的低功耗模式,直接一个WFI指令就可以了。

实际测试中,我们就是直接在程序运行结束之后来一个asm("WFI");,这样QEMU直接也就停止仿真运行了,CPU占用直接降到最低,是一个非常不错的解决方法。即使忘记退出QEMU也不会因为资源占用过高而对宿主系统产生影响。

当然,我们还可以通过给QEMU进行资源分配限制,这样即使QEMU运行的时候也不会出现资源100%的占用,就像VPS里面那样,不过这种方式稍微有些复杂,并且会影响仿真速度,除非用户的程序真的要连续不停的运行,否则使用WFI的方式还是非常不错的。

最后,当仿真运行结束的时候可以通过ctrl + A X退出仿真器。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

相关文章

发表新评论