Address of labels (MSVC)(标签地址 (MSVC))
问题描述
我们正在为高级编译语言编写字节码,经过一些分析和优化,很明显当前最大的性能开销是我们用来跳转到字节的 switch 语句-代码案例.
We are writing a byte-code for a high-level compiled language, and after a bit of profiling and optimization, it became clear that the current largest performance overhead is the switch statement we're using to jump to the byte-code cases.
我们调查了提取每个案例标签的地址并将其存储在字节码流本身中,而不是我们通常打开的指令 ID.如果这样做,我们可以跳过跳转表,直接跳转到当前执行指令的代码位置.这在 GCC 中非常有效,但是,MSVC 似乎不支持这样的功能.
We investigated pulling out the address of each case label and storing it in the stream of byte-code itself, rather than the instruction ID that we usually switch on. If we do that, we can skip the jump table, and directly jump to the location of code of the currently executing instruction. This works fantastically in GCC, however, MSVC doesn't seem to support a feature like this.
我们尝试使用内联汇编来获取标签的地址(并跳转到它们),并且它有效,但是,使用内联汇编会导致 MSVC 优化器避免整个函数.
We attempted to use inline assembly to grab the address of the labels (and to jump to them), and it works, however, using inline assembly causes the entire function to be avoided by the MSVC optimizer.
有没有办法让优化器仍然在代码上运行?不幸的是,我们不能将内联汇编提取到另一个函数中,而不是制作标签的那个函数,因为即使在内联汇编中也无法引用另一个函数的标签.有什么想法或想法吗?非常感谢您的意见,谢谢!
Is there a way to allow the optimizer to still run over the code? Unfortunately, we can't extract the inline assembly into another function other than the one that the labels were made in, since there's no way to reference a label for another function even in inline assembly. Any thoughts or ideas? Your input is much appreciated, thanks!
推荐答案
在 MSVC 中这样做的唯一方法是使用内联汇编(这对于 x64 来说基本上是你的烦恼):
The only way of doing this in MSVC is by using inline assembly (which basically buggers you for x64):
int _tmain(int argc, _TCHAR* argv[])
{
case_1:
void* p;
__asm{ mov [p],offset case_1 }
printf("0x%p
",p);
return 0;
}
如果你打算做这样的事情,那么最好的方法是在汇编中编写整个解释器,然后通过链接器将其链接到主二进制文件(这就是 LuaJIT 所做的,这是导致虚拟机的速度非常快,当它没有运行 JIT 代码时).
If you plan on doing something like this, then the best way would be to write the whole interpreter in assembly then link that in to the main binary via the linker (this is what LuaJIT did, and it is the main reason the VM is so blindingly fast, when its not running JIT'ed code that is).
LuaJIT 是开源的,所以如果你走这条路,你可能会从中得到一些提示.或者,您可能想查看forth 的来源(其创建者开发了您尝试使用的原理),如果有一个 MSVC 版本,你可以看到他们是如何完成它的,否则你会被 GCC 困住(这不是坏事,它适用于所有主要平台).
LuaJIT is open-source, so you might pick up some tips from it if you go that route. Alternatively you might want to look into the source of forth (whose creator developed the principle you're trying to use), if there is an MSVC build you can see how they accomplished it, else you're stuck with GCC (which isn't a bad thing, it works on all major platforms).
这篇关于标签地址 (MSVC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:标签地址 (MSVC)
基础教程推荐
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31