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

edA*_*a-y 5 c++ gcc

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

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

while(true)
{
  uint8_t cmd = *code++;
  switch( cmd )
  {
    case op_1: ...; break;
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

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

我看到的一个选项是GCC特定于使用带标签地址的动态转到.break我可以直接跳到下一条指令,而不是在每种情况的最后.我曾希望优化器会为我做这个,但是看一下反汇编它显然不会:大多数op_codes结束时会有一个重复的持续跳转.

如果相关,则VM是基于寄存器的简单机器,具有浮点和整数寄存器(每个寄存器8个).没有堆栈,只有一个全局堆(该语言并不复杂).

Cra*_*ray 3

一个非常简单的优化是,代替 switch /case/case/case/case/case,

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

switch(cmd)
Run Code Online (Sandbox Code Playgroud)

只是做一个

array[cmd]()
Run Code Online (Sandbox Code Playgroud)

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

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

否则,将是研究哈希表,但我假设您没有那么多命令,在这种情况下,执行哈希函数的开销可能会比不执行切换花费更多。(或者有一个非常简单的哈希函数)