我的项目有一个VM,它执行从特定域语言编译的字节码。我正在研究如何提高字节码的执行时间。作为第一步,我想看看是否有一种方法可以简单地改进字节码解释器,然后再进行机器代码编译。
解释器的主循环如下所示:
while(true)
{
uint8_t cmd = *code++;
switch( cmd )
{
case op_1: ...; break;
...
}
}
问题:是否有更快的方法来实现这个循环而不求助于汇编程序?
我看到的一个选项是GCC特定于使用带有标签地址的dynamic。我可以直接跳到下一条指令,而不是在每一种情况的结尾处使用break
。我本来希望优化器能帮我做到这一点,但从拆卸的角度看,它显然并非如此:在大多数op_codes的末尾,总是会有一个不断的跳变。
如果相关的话,VM是一个简单的基于寄存器的机器,具有浮点数和整数寄存器(每个寄存器有8个)。没有堆栈,只有全局堆(该语言没有那么复杂)。
发布于 2011-04-11 05:33:29
一个非常简单的优化是,不是切换/情况/情况,
只需定义一个带有函数指针的数组(每个函数将处理指定的命令,或者一对命令,在这种情况下,可以将数组中的多个条目设置为同一个函数,并且函数本身可以检查确切的代码),而不是
switch(cmd)
只要做一个
array[cmd]()
这是因为您没有太多的命令。此外,如果您没有定义所有可能的命令(可能只有300个命令,但是您必须使用2个字节来表示它们,所以不要定义包含65536项的数组,只需检查命令是否小于301,如果不是,就不要进行查找)。
如果您不这样做,那么至少对开关语句开头最常用的命令进行排序。
否则,就需要查看哈希表,但我假设您没有那么多命令,在这种情况下,执行哈希函数的开销可能比不需要进行切换花费更大。(或者有一个非常简单的散列函数)
发布于 2011-04-11 05:35:25
建筑是什么?您可能会得到一个与字对齐操作码的速度,但它会吹灭您的代码大小,这意味着您将不得不平衡它和缓存错过的成本。
发布于 2011-04-11 06:05:28
我看到很少有明显的优化,
cmd
而不是switch()
,那么直接使用指针间接,switch( *code++ )
。对于更长的while(true)
循环,这可能没有多大帮助。switch()
,您可以使用continue
而不是break
。因为当continue
在if/else
或switch
中使用时,编译器知道执行必须跳转到外部循环;对于break
(关于switch
)则不是这样。希望这能帮上忙。https://stackoverflow.com/questions/5622030
复制相似问题