【发布时间】:2011-09-19 06:28:36
【问题描述】:
我们正在为高级编译语言编写字节码,经过一些分析和优化后,很明显当前最大的性能开销是我们用来跳转到字节的 switch 语句-代码案例。
我们调查了提取每个案例标签的地址并将其存储在字节码流本身中,而不是我们通常打开的指令 ID。如果这样做,我们可以跳过跳转表,直接跳转到当前执行指令的代码位置。这在 GCC 中非常有效,但是,MSVC 似乎不支持这样的功能。
我们尝试使用内联汇编来获取标签的地址(并跳转到它们),它可以工作,但是,使用内联汇编会导致整个函数被 MSVC 优化器避免。
有没有办法让优化器仍然在代码上运行?不幸的是,我们无法将内联汇编提取到另一个函数中,而不是制作标签的那个函数,因为即使在内联汇编中也无法引用另一个函数的标签。有什么想法或想法吗?非常感谢您的意见,谢谢!
【问题讨论】:
-
你试过函数指针吗?
-
在字节码中放置函数地址而不是标签地址如何?然后,每个指令 ID 都有一个函数。除非您的 fetch-execute 循环在您的带有标签的大函数中。
-
如果我对每种情况都使用函数并使用函数指针而不是标签地址,它会起作用。但是,我觉得函数调用开销太大了,以至于它会抵消任何性能提升,即使函数是微不足道的(没有参数,没有返回)。不过我会尝试一下,感谢您的发帖。
-
如果我对您正在使用的硬件的猜测正确,那么函数调用开销的问题是间接分支引起的管道泡沫,在某些情况下无法预测-订购 PowerPC 处理器。但是无论如何,您仍然会遇到带有计算 goto 的相同气泡——事实上,在 ABI 级别,函数指针 is 是计算 goto。如果您使用 FASTCALL 约定,函数参数将在寄存器中传递,因此它们不会影响整体运行时间,因为 mov 无论如何都适合间接气泡。
-
@Rovert 虽然这对你来说为时已晚,但对于未来的读者来说:当涉及到低级性能时,你应该假设 nothing 并基准 everything我>。您可能是对的,但是您应该检查并重新检查每个新的 architecture 和编译器 version,因为它可能会发生变化。
标签: c++ assembly label inline-assembly goto