【问题标题】:How to force c++ compiler to use registers?如何强制 c++ 编译器使用寄存器?
【发布时间】: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


【解决方案1】:

register 关键字只是一个提示,大多数现代编译器都会忽略它。从本质上讲,这是因为编译器比程序员更擅长优化和找出应该放在寄存器中的内容。

因此,您不能强制编译器使用寄存器,即使可以也不应该这样做。如果您想获得最佳速度,请在编译器设置中打开最大优化级别。

【讨论】:

  • 绝对让编译器为你做这件事。
  • 你是对的。当我尝试更改循环时,有时我是寄存器,有时它是一个双字 Ptr。强制编译器似乎是不可能的。
  • @Bizz,x86 在 32 位模式下的寄存器数量非常有限。如果您在循环内有函数调用(看起来确实如此),则可能无法仅将值保留在寄存器中。编译器通常对每个操作应用特殊的成本模型,以便选择合适的存储。阻塞一个寄存器会严重限制优化器,并可能导致其他昂贵的加载/存储。所以我会坚持编译器提示,特别是对于可移植代码。
  • 错误。您从未遇到过 C 代码无法在嵌入式设备上按预期工作的问题,并且如果不使用精确的寄存器访问序列,外围设备将无法工作
【解决方案2】:

在您的情况下,如果您提供正确的优化选项,编译器很可能会使用寄存器。

通常,将变量强制放入寄存器的唯一方法是使用内联汇编。

【讨论】:

  • Opt 级别在 /Ox 上,但内联汇编成功了。谢谢。
猜你喜欢
  • 2013-07-22
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2012-01-09
  • 2010-09-18
  • 1970-01-01
相关资源
最近更新 更多