【发布时间】:2010-09-23 19:41:17
【问题描述】:
我正在阅读 K&R 并来到关于寄存器变量的小部分,想知道这里的人们是否有一些很好的实践示例。
来自 K&R 中的第 4.7 节:
寄存器声明看起来像
注册 int x;
注册字符 c;
明确地说,我只是希望看到一些很酷的代码示例。我(很确定我)理解主题,所以不需要输入冗长的解释(除非你愿意)。
【问题讨论】:
标签: c cpu-registers kernighan-and-ritchie kr-c
我正在阅读 K&R 并来到关于寄存器变量的小部分,想知道这里的人们是否有一些很好的实践示例。
来自 K&R 中的第 4.7 节:
寄存器声明看起来像
注册 int x;
注册字符 c;
明确地说,我只是希望看到一些很酷的代码示例。我(很确定我)理解主题,所以不需要输入冗长的解释(除非你愿意)。
【问题讨论】:
标签: c cpu-registers kernighan-and-ritchie kr-c
在使用现代编译器(阅读:过去 15 年以上)时,没有很好的寄存器使用示例,因为它几乎从来没有做过任何好事,而且可能会做一些坏事。当您使用 register 时,您是在告诉编译器“我知道如何比您更好地优化我的代码”,这几乎从来没有发生过。使用 register 时可能会发生以下三种情况之一:
即使一个编译器在您使用寄存器时生成更好的代码,也没有理由相信另一个编译器会做同样的事情。如果你有一些关键代码编译器优化得不够好,你最好的选择可能是使用汇编程序来处理该部分,但当然首先要进行适当的分析以验证生成的代码确实是一个问题。
【讨论】:
register 关键字不是关于硬件寄存器,而是关于优化。它唯一的作用就是不能取这样一个变量的地址。特别是它可以用于变量的资产别名,这非常有用。
register:获取变量的地址是无效的,它不能忽略它。这是关键字的唯一作用:生成额外的检查和错误来帮助人类。
总的来说,我同意Robert,但作为任何好的规则,这个规则也有例外。
如果您在深度嵌入式系统上工作,您可能比编译器更了解如何为在特定硬件架构上的特定应用程序优化代码。
但在 99% 的情况下,罗伯茨的解释也适用于嵌入词。
【讨论】:
我知道这是很久以前的事了,但这里是 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 关键字的算法,并执行它以在我的笔记本上对一个包含 50,000,000 个元素的随机数组进行排序,每个版本几次。
寄存器的使用将堆排序时间从 ~135s 减少到 ~125s。
我也只测试了 5,000,000 个元素,但执行次数更多。
没有寄存器的版本从 11s 开始,但每次执行都会降低时间,直到达到 9,65s 并停止
带寄存器的版本从 10s 开始,将时间降低到 8,80s。
我认为这与缓存内存有关。尽管如此,寄存器似乎使算法速度更快
由于这些变量在算法中被大量使用,通过确保它们在寄存器上而不是将这项工作留给编译器,在这种情况下会产生更好的结果。但是,它并没有改善那么多时间。
希望 thill 对某人有所帮助,问候。
【讨论】:
另一个常见的情况是在实现低级解释器时。在寄存器中保存一些状态,例如。虚拟机堆栈指针,可以显着减少内存访问并加快您的代码速度。
有关优化示例(5.2 栈顶缓存),请参阅 vmgen — a generator of efficient virtual machine interpreters。
【讨论】:
首先,寄存器变量应该用于频繁使用的变量,例如循环控制变量,以通过最小化访问时间来提高性能。在这种情况下,您只能使用并且只能注册存储说明符 喜欢,有趣(auto int a,auto int b):错误 fun (register int a,register int b) : 只运行这个 有趣(静态int a,静态int b):错误 fun (extern int a,extern int b) :error
【讨论】:
register 绝对是其中之一。
这是一个需要多个答案的问题,因为有多个编码上下文:从高级语言的角度来看,中级和低级(下至汇编),因为 C 语言可以调用汇编例程。
使用汇编而不是 C 的原因很明显是因为在开发过程中遇到了性能问题,所以是的,需要 register 关键字,但在许多情况下,它并没有按照开发人员的预期工作
【讨论】: