我正在通过K& R阅读并找到关于寄存器变量的小部分,并想知道这里的人是否有一些很好的例子付诸实践。
来自K& R的第4.7节:
登记声明看起来像是 注册int x;
注册char c;
要清楚,我只是希望看到一些很酷的代码示例。我(很确定我)理解主题,所以不要觉得需要输入详细的解释(除非你想)。
答案 0 :(得分:68)
使用现代编译器(阅读:过去15年以上)没有很好的寄存器使用示例,因为它几乎从来没有任何好处,可以做一些坏事。当你使用寄存器时,你告诉编译器“我知道如何比你更好地优化我的代码”,这几乎不是这种情况。使用register时可能会发生以下三种情况之一:
即使一个编译器在使用寄存器时产生更好的代码,也没有理由相信另一个编译器也会这样做。如果你有一些关键代码,编译器没有很好地优化你最好的选择可能是使用汇编程序,但当然要做适当的分析来验证生成的代码是否真的是一个问题。
答案 1 :(得分:12)
一般来说,我同意Robert,但作为任何好的规则,这个也有例外 如果您使用深度嵌入式系统,您可能比编译器更了解如何优化特定硬件架构上的特定应用程序的代码。
但在99%的案例中,罗伯茨的解释也适用于嵌入词。
答案 2 :(得分:4)
我知道这已经有一段时间了,但是这里是一个来自heapsort的子过程的实现,其中使用寄存器变量使算法更快,至少使用gcc 4.5.2来编译代码
inline void max_heapify(int *H, int i){
char OK = FALSE;
register int l, r, max, hI;
while(!OK){
OK = TRUE;
l = left(i);
r = right(i);
max = i;
if(l <= H[SIZE] && H[l] > H[i]){
max = l;
}
if(r <= H[SIZE] && H[r] > H[max]){
max = r;
}
if(max != i){
OK = FALSE;
hI = H[i];
H[i] = H[max];
H[max] = hI;
i = max;
}
}
}
我在属性之前测试了带有和没有register关键字的algortihm,并执行它以在我的笔记本上对50,000,000个元素的随机数组进行排序,每个版本都有几次。
寄存器的使用使得整个时间从~135秒减少到~125秒。
我还测试了5,000,000个元素,但执行了更多次。
没有寄存器的版本从11点开始,但每次执行都会降低时间,直到它达到9,65秒并停在它上面
寄存器的版本从10s开始,并将时间降低到8,80s。
我认为这与缓存有关。尽管如此,寄存器似乎通过一个常数因子使算法更快
由于这些变量在算法中被广泛使用,因此通过确保它们在寄存器上而不是将这项工作留给编译器导致在这种情况下更好的结果。但是,这并没有改善时间。
希望这会对某人有所帮助,问候。
答案 3 :(得分:3)
另一个常见的情况是实施低级解释器。在寄存器中保持一些状态,例如。虚拟机堆栈指针,可以显着减少内存访问并加快代码速度。
有关优化的示例,请参阅vmgen — a generator of efficient virtual machine interpreters(5.2堆栈缓存顶部)。
答案 4 :(得分:1)
首先,寄存器变量应该用于频繁使用的变量,例如循环控制变量,以通过最小化访问时间来提高性能。在这种情况下,您只能使用辅助,并且只能注册存储说明符 喜欢,有趣(auto int a,auto int b):错误 fun(注册int a,注册int b):只有这个才能运行 fun(static int a,static int b):error fun(extern int a,extern int b):error
答案 5 :(得分:0)
这是一个需要多个答案的问题,因为存在多个编码上下文:从高级语言的角度来看,由于C语言可以调用汇编例程,因此是中级和低级(直到汇编)。
使用汇编语言代替C语言的原因很广泛,因为在开发过程中遇到了性能问题,所以需要使用register关键字,但是在很多情况下,它不能按开发人员的预期工作