我们必须只使用寄存器变量?

时间:2014-02-27 06:16:43

标签: c variables compiler-construction storage cpu-registers

我们知道register variablefaster accessible,而compilerregister variable创建register int val; 的任何变量。

register variable

我只是想知道“是否有任何情况/应用 我们必须只使用{{1}} 而其他变量在这种情况下无效? “

如果你能放一段代码,那就明白了。

3 个答案:

答案 0 :(得分:7)

“我们知道” - 实际上我们不知道

register是编译器的建议,而非要求。对于当今疯狂优化的编译器来说,它很少需要。从目前的(C11)标准:

  

具有存储类说明符寄存器的对象的标识符声明   建议尽可能快地访问对象。这种程度的程度   建议是有效的是实施定义。

所以可以进入注册表。它还可以进入更快的内存,常规内存或甚至在磁盘上,或在内蒙古的服务器上,以惩罚编码人员使用不必要的关键字: - )

t 使用它 - 通常,你应该忘记它。它和auto一样有用。

举例来说,让我们假设一个相当“低于优化”的编译器将每个C指令视为一个单元。通过这个,我的意思是:

int x = 1;
x = x + 7;
x = x - 2;
useX (x);

将转换为程序集(经典的加载存储架构):

loadi  r0,  1          ; set r0 to 1
stor   r0,  [x]        ; store to memory

load   r0,  [x]        ; load from memory
addi   r0,  7          ; add 7
stor   r0,  [x]        ; store to memory

load   r0,  [x]        ; load from memory
subi   r0,  2          ; subtract 2
stor   r0,  [x]        ; store to memory

load   r0,  [x]        ; load from memory
call   useX            ; call the function

换句话说,没有优化意识到该值在添加后仍然在r0中,因此无需再次加载它。

在这样一个(脑死亡的)编译器中,使用register可以提供非常方便的效率。代码:

register int x = 1;
x = x + 7;
x = x - 2;
useX (x);

可能会产生更好的代码:

loadi  r0,  1          ; set r0 to 1
addi   r0,  7          ; add 7
subi   r0,  2          ; subtract 2
call   useX            ; call the function

当然,所有这些都取决于编译器以及它如何使用寄存器。我给出的代码只是一个人为的例子。正如我所说,使用现代编译器,它很少是必要的。


最重要的是,在回答您的具体问题时“有没有任何情况/应用,我们 只使用寄存器变量而其他变量对这种情况没有用?”,答案是否定的。如果它是真正的C编译器,则不需要使用register关键字。

答案 1 :(得分:3)

没有必须使用register的情况。但除了它似乎是城市传说之外,register在C程序中具有语义含义:使用register而不是auto声明的变量,默认情况下,不能成为主题到&,所以他们的地址不能被采纳。这意味着它们永远不能与其他变量别名,因此register仅仅是一个优化提示,就像restrict一样。

答案 2 :(得分:1)

有一种情况是,不仅要暗示你的编译器为变量分配一个寄存器,而是为它命名一个特定的寄存器(然后不允许忽略register关键字):实现高效线程虚拟机。

这种方法的一个很好的例子是OCaml bytecode interpreter

在任何其他需要混合C和汇编代码的情况下,手动将C变量映射到寄存器是必不可少的。