【发布时间】:2012-11-25 16:32:40
【问题描述】:
我的(c++ .Net Win32 控制台)代码中有一个for 循环,它必须尽可能快地运行。所以我需要让编译器使用 register 而不是将其存储在 RAM 中。
MSDN 说:
register 关键字指定该变量将存储在一个 机器注册,如果可能。
这是我尝试过的:
for(register int i = 0; i < Size; i++)
当我查看编译器生成的反汇编代码时,我看到:
012D4484 mov esi,dword ptr [std::_Facetptr<std::codecvt<char,char,int> >::_Psave+24h (12DC5E4h)]
012D448A xor ecx,ecx
012D448C push edi
012D448D mov edi,dword ptr [std::_Facetptr<std::codecvt<char,char,int> >::_Psave+10h (12DC5D0h)]
012D4493 mov dword ptr [Size],ebx
012D4496 test ebx,ebx
012D4498 jle FindBestAdd+48h (12D44B8h) //FindBestAdd is the function the loop is in
012D449A lea ebx,[ebx]
我希望汇编代码不会在我使用 register 关键字的地方生成 dword ptr。
那么,我怎么知道编译器是否可以使用寄存器以及我应该怎么做才能强制编译器直接从寄存器读取/写入寄存器。
【问题讨论】:
-
指定您的编译器选项和
Size的声明以及任何其他可能不寻常的内容。我的gcc使用寄存器很好,即使没有打开优化。 VC 没有理由做得更糟。 -
我看不出反汇编如何匹配源代码:也许您需要发布更多源代码和更多反汇编。你的问题的理论答案是,a)知道你是否有可能需要知道编译器的实现; b) C++ 不允许你强制编译器注册……充其量,
register关键字只是一个提示。 -
您确定您发布的反汇编实际上是for循环吗?无论哪种方式,
register关键字只是对编译器的提示,但由于现在的编译器在为它们生成的代码分配寄存器方面比大多数人要好得多,因此他们可以选择忽略该提示。我建议使用分析器,以便您可以找到程序中真正重要的优化瓶颈。 -
获取寄存器最简单的方法是切换到x64。 x86 通常没有足够的寄存器。看看你的代码:它已经在使用 EBX、ECX、ESI 和 EDI。剩下的就是 EAX 和 EDX,但它们可能也在使用中。
push edi看起来像一个寄存器溢出到堆栈,这意味着所有寄存器都在使用中。
标签: c++ performance assembly compiler-construction cpu-registers