我在C中编写了一个虚拟机,它有一个调用表,其中填充了指向提供VM操作码功能的函数的指针。当虚拟机运行时,它首先解释一个程序,创建一个索引数组,该索引数组对应于所提供操作码的调用表中的相应函数。然后它循环遍历数组,调用每个函数直到它到达结尾。
每条指令都非常小,通常是一行。适合内联。问题是编译器不知道何时将调用任何虚拟机的指令,因为它是在运行时决定的,所以它不能内联它们。函数调用和参数传递的开销正在扼杀我的VM的性能。关于如何解决这个问题的任何想法?
答案 0 :(得分:5)
以下是一些减少开销的选项:
fastcall
(或类似的东西)以减少参数传递的开销最终,您将进入JIT编译,在线分析和重新优化以及各种其他令人敬畏的东西。
答案 1 :(得分:2)
您可能需要研究许多好的技巧。以下是我熟悉的两个:
Inline caching - 基本上,找到被调用的内容,然后从vtable查找切换到只添加一堆if语句,这些语句分派到静态已知位置。这种技术在Self语言中发挥了很大作用,是JVM的主要优化之一。
跟踪 - 为可能最终使用的每种类型编译一个多态分派的版本,但推迟编译直到代码运行了很多次。 Mozilla's TraceMonkey JavaScript解释器在很多情况下使用它来获得巨大的性能提升。
希望这有帮助!