使用仿真实现虚拟化
- 7 分钟
现在,我们已了解虚拟化 ISA 的条件以及 CPU 虚拟化的两种主要类型(全虚拟化和半虚拟化),接下来将讨论用于实现全虚拟化和处理 VM 的仿真技术。 回想一下,仿真是允许在具有不同接口和功能(目标)的系统上实现一个系统(源)的接口和功能的过程。 当来宾和主机 ISA 不同时,仿真是唯一可用的 CPU 虚拟化机制。 如果来宾和主机 ISA 相同,则可以(可能)应用直接本机执行。
通过解释或二进制翻译执行仿真。 借助解释,可将源指令转换为相关的目标指令(一次转换一个指令)。 解释相对较慢,因为需要逐一仿真指令且没有任何优化 技术(例如,阻止解释已遇到并解释过的指令)。 二进制翻译将源指令块转换为目标指令并缓存生成的块以重复使用,以便优化解释。 通常,指令块比单个指令更适合优化。 与解释相比,二进制翻译的速度要快得多,原因是应用了块缓存和块代码优化。 在下面的视频中,我们将讨论三个主要解释方案:解码和调度、间接线程和直接线程。
如视频中所述,基本解释器应按指令通读源代码指令,分析每个指令,并调用相关的例程来生成目标代码。 解码和调度解释器应用基本解释,但会引发大量的分支(或跳转)指令(直接和间接),从而导致执行时间不佳。 作为解码和调度的优化,间接线程解释器将部分调度代码追加(或线程处理)到每个解释器例程的末尾,尝试发布某些解码和调度分支。 最后,一种名为直接线程的更高级解释器尝试仅解释一次重复操作来改善间接线程。 尽管直接线程解释器改进了间接线程以及解码和调度分支,但仍存在重要缺点,如大量内存映像和受限可移植性。 在下一个视频中,我们将讨论二进制翻译,这实质上是针对直接线程解释的限制。
正如此视频中所示,二进制翻译尝试通过以下方式来摊销直接线程解释器导致的提取和分析成本:(1) 将源指令块(而不是单个指令)翻译为目标指令块,(2) 尝试缓存翻译后的代码,以便多次保存解释源指令。 下表根据四个指标对二进制翻译、解码和调度、间接线程和直接线程仿真技术进行了比较:内存需求、启动性能、稳定状态性能和代码可移植性。 例如,解码和调度解释器行读取如下:首先,对于解码和调度,内存要求保持较低,因为目标 ISA 中的每个指令类型仅有一个解释器例程。 此外,解码和调度避免在每个例程结束时线程处理调度代码。 其次,启动性能很快,因为既不对源二进制进行预译码,也不能对其进行翻译。 第三,稳定状态性能(即启动解释器后的性能)很慢,因为有大量分支并且需要解释每个外观的每条指令。 最后,代码可移植性非常好,因为解码和调度解释器不应用带有解释器例程地址的预译码,这点与直接线程解释器不同。
| 内存需求 | 启动性能 | 稳定状态性能 | 代码可移植性 | |
|---|---|---|---|---|
| 解码和调度解释器 | 低 | 快速 | 慢 | 完好 |
| 间接线程解释器 | 低 | 快速 | 慢 | 完好 |
| 直接线程解释器 | 高 | 慢 | 中 | 中 |
| 二进制翻译 | 高 | 非常慢 | 快速 | 差 |