我了解了注册
示例:
register int a;
说编译器更快地使用变量(在寄存器中保存我的int变量) 但如果没有处理器中的寄存器 - 对于我的变量集 auto
iPhone ARM处理器可以有这个特殊的寄存器吗?答案 0 :(得分:3)
任何处理器都有寄存器(非常罕见且现在已经死的基于堆栈的架构除外)。 C中的关键字register
只是编译器将该变量映射到寄存器而不是堆栈中的提示。当来自将变量映射到寄存器的算法不那么有效时,这来自“古代”时代。现在这些算法比人类更好地映射,因此实际上不需要使用register
提示。
我真的不了解iPhone ARM编译器,但我真的不认为他们不使用现代算法将变量映射到寄存器。
另请注意,我告诉您的内容对于使用优化标记进行编译是有效的。
寄存器是处理器具有的最快内存,它驻留在CPU内部,它们以处理器的速度运行,并且没有时间限制来访问它。但是,寄存器是有限的,很少,从4-6个通用寄存器(在CISC架构上)到10-20个寄存器(在RISC架构上)。编译器将尝试将大多数使用的访问的变量映射到这些寄存器。当他用完寄存器时,他必须在堆栈上映射变量,这要慢得多(它在RAM中,但主要是缓存在缓存L1或L2中)。
因此,决定哪些变量映射到寄存器以及哪些变量映射到堆栈上会对性能产生重大影响,但正如我所说,现在编译器在将变量映射到寄存器方面比人类做得更好。 / p>
答案 1 :(得分:1)
Bolov提供了一个相当不错的答案。但是,register
上还有几个额外的点。
首先,您可能不会获取register
变量的地址。对于大多数编译器,auto
变量被跟踪并注释为由指针引用,它通常不会产生影响。但是,可能存在编译器无法确定指针不是别名变量的情况,在这种情况下,register
变量实际上可能更好。由于变量声明为register
,因此无法通过指针对其进行别名处理。有关别名的更多信息,请参阅restrict
关键字的信息。
具有讽刺意味的是,这可能会在较低的优化级别下发挥作用。
如果您明确声明要与 clang 或 gcc 语法一起使用的寄存器,则需要类似的内容,
register unsigned int *stack asm("sp");
需要 register
才能使变量stack
指向堆栈的顶部。这是“C”语言的扩展,但它与iOS及其常见编译器相关。
在一个极其复杂的算法中,使用register
可以提示编译以将值保存在内存中(有利于其他变量)。通常,像inline
一样,最好让编译器决定。除非你做了大量的分析,发现编译器正在堆栈中保存一个常用的变量。
如果您没有过度使用关键字,它也可以作为变量对性能至关重要的文档;虽然在这种情况下评论可能同样好。
要使register
关键字在ARM(r0-r15)上有所不同,您需要一个非常复杂的算法和大型函数体。它可能在 thumb 模式下更有用,其中可用的寄存器更少;对于iOS ARM设备,这不适用。
通常不需要register
。也可以想象,过度使用实际上可能导致更差执行代码。它不应该是添加此关键字的自动反射,只应在代码完全正常并且优化阶段已经开始之后才能完成。