c++ - 最佳虚拟机/字节码解释器循环

标签 c++ gcc

我的项目有一个 VM,它执行从特定领域语言编译的字节码。我正在寻找可以提高字节码执行时间的方法。作为第一步,我想看看是否有一种方法可以在我冒险进行机器代码编译之前简单地改进字节码解释器。

解释器的主循环如下所示:

while(true)
{
  uint8_t cmd = *code++;
  switch( cmd )
  {
    case op_1: ...; break;
    ...
  }
}

问题:有没有更快的方法来实现这个循环而不求助于汇编程序?

我看到的一个选项是 GCC 特定于使用带有标签地址的动态 goto。我可以直接跳转到下一条指令,而不是在每个案例结束时使用 break。我曾希望优化器会为我做这件事,但从反汇编来看它显然没有:在大多数 op_code 的末尾都有一个重复的常量跳转。

如果相关的话,VM 是一个简单的基于寄存器的机器,带有浮点和整数寄存器(每个寄存器 8 个)。没有栈,只有全局堆(那个语言没那么复杂)。

最佳答案

一个非常简单的优化是,而不是 切换/案例/案例/案例/案例/案例,

只需定义一个带有函数指针的数组(其中每个函数将处理一个指定的命令,或者在这种情况下您可以将数组中的多个条目设置为同一个函数的几个命令,并且该函数本身可以检查确切的代码), 而不是

switch(cmd)

做一个

array[cmd]()

这是因为您没有太多命令。另外,做一些检查,如果你不会定义所有可能的命令(也许你只有 300 个命令,但你必须使用 2 个字节来表示它们,所以不要定义一个包含 65536 个项目的数组,只需检查命令是否更少超过 301,如果不是,则不要进行查找)

如果您不这样做,至少将最常用的命令排序在 switch 语句的开头。

否则它会查看散列表,但我假设您没有那么多命令,在这种情况下,执行散列函数的开销可能比不执行 switch 花费更多。 (或者有一个非常简单的散列函数)

关于c++ - 最佳虚拟机/字节码解释器循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5622030/

相关文章:

c++ - 为什么 C/C++ 字符串文字声明必须是单行的?

c++ - (struct in_addr **) 和 *(struct in_addr *) 之间的区别

c++ - 我们可以在 C++17 中检测到 "trivial relocatability"吗?

c - 为什么 gcc 允许向长度为 2 的 char 数组输入两个以上的字符?

来自可执行文件的控制流程图?

c++ - 重新哈希由列表 vector 组成的哈希表 C++

c++ - QtQuick 双屏支持

c++ - LD_LIBRARY_PATH 和 LD_LIBRARY_PATH 有什么区别?

linux - Arch Linux 没有 i586-elf-gcc 或 i586-elf-gcc

c - 如何阻止 GCC 破坏我的 NEON 内在函数?