我处于两难境地,对于VM的循环来说,性能更好的选项是什么:
选项1 - 强制内联指令函数,使用计算goto for switch来调用该标签上的指令的调用(有效内联代码)......或者......
选项2 - 使用函数指针的查找数组,每个指向一个fastcall
函数,指令确定索引。
基本上,更好的是,具有跳转地址和内联代码的查找表或具有fastcall
函数地址的查找表。是的,我知道,两者实际上只是内存地址和来回跳转,但我认为如果超出寄存器空间,fastcall
仍可能导致某些数据被压入堆栈,即使强制使用寄存器参数。
编译器是GCC。
答案 0 :(得分:1)
我认为,对于“虚拟机”,你指的是执行某种字节码的模拟处理器,类似于“Java虚拟机”,而不是整个模拟计算机,它允许安装另一个操作系统(如VirtualBox)器/ VMware)。
我的建议是让编译器做出关于什么具有最佳性能的决定,并在字节代码流的当前项上创建一个大的传统“切换”。这可能会导致编译器创建一个跳转表,因此它与计算的goto变量一样快(或慢),但更便携。
您的变体2 - 查找函数指针数组 - 可能比内联函数慢,因为非内联函数可能会产生额外开销,例如返回值的处理。毕竟,你的一些VM-op函数(如“goto”或“set-register-to-immediate”)必须修改指令指针,其他函数则不需要。
通常,对当前CPU的函数指针(或通过跳转表跳转)的调用很慢,因为很难通过分支预测来预测它们。因此,如果您考虑优化VM,请尝试查找一组指令,这些指令需要尽可能少的代码点。