什么';C语言中寄存器变量用法的一个很好的例子是什么?

什么';C语言中寄存器变量用法的一个很好的例子是什么?,c,cpu-registers,kernighan-and-ritchie,kr-c,C,Cpu Registers,Kernighan And Ritchie,Kr C,我正在阅读K&R,来到了关于寄存器变量的小部分,我想知道这里的人们是否有一些很好的例子用于实践 根据K&R第4.7节: 寄存器声明看起来像 寄存器int x 寄存器字符c 说清楚,我只是希望看到一些很酷的代码示例。我(非常肯定我)理解主题,所以不需要输入详细的解释(除非你愿意)。在使用现代编译器(阅读:过去15年以上)时,没有使用寄存器的好例子,因为它几乎没有任何好处,也可能有一些坏处。当您使用register时,您告诉编译器“我知道如何比您更好地优化代码”,这几乎是不可能的。使用registe

我正在阅读K&R,来到了关于寄存器变量的小部分,我想知道这里的人们是否有一些很好的例子用于实践

根据K&R第4.7节:

寄存器声明看起来像
寄存器int x
寄存器字符c


说清楚,我只是希望看到一些很酷的代码示例。我(非常肯定我)理解主题,所以不需要输入详细的解释(除非你愿意)。

在使用现代编译器(阅读:过去15年以上)时,没有使用寄存器的好例子,因为它几乎没有任何好处,也可能有一些坏处。当您使用register时,您告诉编译器“我知道如何比您更好地优化代码”,这几乎是不可能的。使用register时可能发生以下三种情况之一:

  • 编译器会忽略它,很可能是这样。在这种情况下,唯一的危害是不能获取代码中变量的地址
  • 编译器会接受您的请求,因此代码运行较慢
  • 编译器会满足您的请求,代码运行得更快,这是最不可能出现的情况
即使一个编译器在使用寄存器时生成更好的代码,也没有理由相信另一个编译器也会这样做。如果您有一些关键代码,但编译器没有很好地优化,那么您的最佳选择可能是使用assembler来完成该部分,但当然,首先要进行适当的分析,以验证生成的代码是否确实存在问题。

一般来说,我同意,但任何好的规则都有例外。
如果您使用的是深度嵌入式系统,您可能比编译器更了解如何在特定硬件体系结构上优化特定应用程序的代码


但在99%的情况下,罗伯茨的解释同样适用于嵌入式单词。

另一种常见情况是在实现低级口译时。在寄存器中保留一些状态,例如虚拟机堆栈指针,可以显著减少内存访问并加快代码速度


请参阅优化示例(5.2堆栈顶部缓存)。

首先,寄存器变量应用于频繁使用的变量,如循环控制变量,以通过最小化访问时间来提高性能。在这种情况下,只能使用和只能使用寄存器存储说明符 比如,fun(autointa,autointb):错误 fun(注册int a,注册int b):对,只有这个才会运行 fun(静态int a,静态int b):错误
fun(extern int a,extern int b):错误

我知道这是很久以前的事了,但这里是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;
        }
    }
}
inline void max\u heapify(int*H,int i){
char OK=FALSE;
寄存器int l、r、max、hI;
而(!OK){
OK=正确;
l=左(i);
r=右(i);
max=i;
if(lh[i]){
最大值=l;
}
if(r H[max]){
max=r;
}
如果(最大!=i){
OK=假;
hI=H[i];
H[i]=H[max];
H[max]=hI;
i=最大值;
}
}
}
我在属性前测试了带有和不带register关键字的算法,并执行它对笔记本上5000万个元素的随机数组进行排序,每个版本都有几次

寄存器的使用将堆启动时间从~135s降至~125s

我还只测试了5000000个元素,但执行了更多次

没有寄存器的版本从11秒开始,但每次执行都会降低时间,直到达到9,65秒并停止

带有寄存器的版本从10秒开始,并将时间降低到8,80秒

我认为这与缓存有关。尽管如此,寄存器似乎使算法更快了一个常数因子

由于这些变量在算法中被大量使用,因此在这种情况下,通过确保它们位于寄存器上而不是将此工作留给编译器,可以获得更好的结果。然而,这并没有使时间有多大的改善


希望这会对某人有所帮助,大家好。

这是一个需要多个答案的问题,因为有多个编码上下文:从高级语言的角度来看,中级和低级(下至汇编),因为C语言可以调用汇编例程


使用汇编而不是C的原因很明显是因为在开发过程中遇到了性能问题,所以是的,需要使用register关键字,但不是。在许多情况下,它并没有按照开发人员的预期工作。

老实说,这与Robert所说的非常相似。实际上你是对的。我重读了这篇文章,最后一段澄清了我想澄清的内容。。。下次我会读得更好“三件事可能发生,两件事不好”?我在哪里听说过…;-)请记住,编译器完全可以忽略您的建议-标准中没有规定必须在寄存器中放入寄存器变量。这个答案产生了相当大的影响,关于这个答案,这个答案有误导性。
register
关键字不是关于硬件寄存器,而是关于优化。它唯一的作用是不能接受这样一个变量的地址。特别是,它可以用于变量的资产别名,这是非常有用的。它没有误导性,完全是错误的。一致性编译器不能忽略
寄存器
:获取变量地址无效,它不能忽略该变量。这是关键字所做的唯一一件事:生成额外的检查和错误