C++ 通过函数指针计算的goto/jump与fastcall相比,哪一个成本更高?

C++ 通过函数指针计算的goto/jump与fastcall相比,哪一个成本更高?,c++,performance,function-pointers,goto,lookup-tables,C++,Performance,Function Pointers,Goto,Lookup Tables,我左右为难,对于VM的循环来说,哪一个性能更好: 选项1-强制内联对于指令函数,使用computed goto for switch转到该标签上指令的调用(有效内联代码)。。。或者 选项2-使用函数指针的查找数组,每个指针指向一个fastcall函数,指令确定索引 基本上,更好的方法是使用跳转地址和内嵌代码的查找表,或者使用fastcall函数地址的查找表。是的,我知道,两者实际上都只是内存地址和来回跳转,但我认为fastcall如果超出寄存器空间,即使被迫使用寄存器作为参数,也可能导致一些数据

我左右为难,对于VM的循环来说,哪一个性能更好:

选项1-强制内联对于指令函数,使用computed goto for switch转到该标签上指令的调用(有效内联代码)。。。或者

选项2-使用函数指针的查找数组,每个指针指向一个
fastcall
函数,指令确定索引

基本上,更好的方法是使用跳转地址和内嵌代码的查找表,或者使用
fastcall
函数地址的查找表。是的,我知道,两者实际上都只是内存地址和来回跳转,但我认为
fastcall
如果超出寄存器空间,即使被迫使用寄存器作为参数,也可能导致一些数据被推送到堆栈上

编译器是GCC。

我假设,“虚拟机”指的是执行某种字节码的模拟处理器,类似于“Java虚拟机”,而不是允许安装另一个操作系统(如VirtualBox/VMware)的整个模拟计算机

我的建议是让编译器来决定什么具有最好的性能,并在字节码流的当前项上创建一个大的传统“开关”。这可能会导致编译器创建一个跳转表,因此它与计算的goto变量一样快(或慢),但更具可移植性

变量2(函数指针的查找数组)可能比内联函数慢,因为非内联函数可能会有额外的开销,例如返回值的处理。毕竟,一些VM op函数(比如“goto”或“set register to immediate”)必须修改指令指针,而其他函数则不需要修改


通常,在当前CPU上对函数指针的调用(或通过跳转表进行跳转)很慢,因为分支预测很难正确预测它们。因此,如果您考虑优化您的虚拟机,请尝试找到一组指令,这些指令需要尽可能少的代码点。

我建议同时尝试这两种方法,并进行评测。同样值得在每种情况下查看生成的汇编程序,以明确编译器正在做什么。@OliCharlesworth-用简单的代码尝试这两种方法可能不会产生实际的结果。在虚拟机中,执行循环的级别较低,因此这不像是几行工作来尝试这两种情况,这就是为什么我提前询问,以便选择更好的解决方案。我认为选项1会更快,但我没有数据来支持这一点。尝试将开关值紧密打包。“计算转到”?我没有看到Fortran标签…@ PeteBecker——在GCC中计算了C和C++的GOTO扩展。不了解其他编译器供应商。基本上,有一个“获取标签地址”操作符可以跳转到。