C# C语言中的寄存器#

C# C语言中的寄存器#,c#,clr,cpu-registers,memory-model,C#,Clr,Cpu Registers,Memory Model,我们都知道堆栈和堆的概念,但我最近读到了第三种保存数据的方法:寄存器 我很难找到关于这种类型的好文章,我找到的是:,还有很多关于C的东西,例如: 到目前为止,我掌握的唯一真实信息是:每个CPU都有自己的寄存器,可以用来保存数据,以尽可能快的方式访问数据,例如在for循环中 据我所知,这是由CLR完成的。然后我想起了这个volatile关键字,如果我们看看MSDN: volatile关键字表示字段可能被修改 同时执行的多个线程。是的字段 声明的volatile不受编译器优化的影响 假设通过单个线程

我们都知道堆栈和堆的概念,但我最近读到了第三种保存数据的方法:寄存器

我很难找到关于这种类型的好文章,我找到的是:,还有很多关于C的东西,例如:

到目前为止,我掌握的唯一真实信息是:每个CPU都有自己的寄存器,可以用来保存数据,以尽可能快的方式访问数据,例如在for循环中

据我所知,这是由CLR完成的。然后我想起了这个volatile关键字,如果我们看看MSDN:

volatile关键字表示字段可能被修改 同时执行的多个线程。是的字段 声明的volatile不受编译器优化的影响 假设通过单个线程进行访问。这确保了 字段中始终存在最新值

那么挥发性物质就是这样吗?它告诉CLR不要使用CPU寄存器,而是堆栈/堆,所有CPU/线程都可以访问堆栈/堆


很抱歉我提出了一个令人困惑的问题,但是关于这个话题的信息实在太少了。

这句话是误导性的,因为它不是一个关于什么的精确定义。Volatile未在编译器优化方面指定。此外,限制编译器在ARM上是不够的。CPU也必须受到限制。我建议你研究一下到底是什么

volatile阻止使用寄存器的说法甚至不是真的。Volatile负载保证Volatile变量的读取频率与程序的读取频率相同,且顺序相同

当你写作时:

volatile int sharedVar = 0;

Console.WriteLine(sharedVar);
Console.WriteLine(sharedVar);
JIT必须精确读取两次。但它仍然可以使用寄存器来存储读取的值

如果CLR能够证明
sharedVar
从未写入,并且始终具有值
0
,它甚至可以删除读取。它可能必须在某些地方插入内存屏障,而不是读取,因为
volatile
访问具有一定的顺序保证。但根本不需要实际发生负载。(当前JIT不进行此优化。)

寄存器是一个实现细节。CLR未在物理实现方面指定。我知道你想知道实施细节,没关系。不过,对于CLR向程序员保证的内容,它们并不重要

“每个CPU都有自己的寄存器”

每个CPU都有一组寄存器,用于涉及任何数据的大多数操作。通常,一条指令将一些数据从内存加载到寄存器中,然后另一条指令对寄存器中的数据进行一些计算

CPU有几个用于数据的寄存器,一些用于指针,还有一些用于跟踪程序执行的特殊寄存器,如指令指针、堆栈指针和标志寄存器

由于CPU有多个寄存器,JIT编译器有时可以使用其中的几个寄存器作为局部变量的存储。寄存器不是在堆栈上分配变量,而是专用于保存变量的值


volatile
关键字不影响寄存器用于存储的方式。如果一个变量可以被不同的线程访问,那么它就不是要存储在寄存器中的候选变量。实际上,存储在寄存器中的只是范围有限、生命周期短的局部变量。

人们过于关注堆和堆栈(有时,就像这里的寄存器)。在99.99%的情况下,你不太可能需要知道你正在处理的对象的实际存储位置。请看。当你在处理某件事情时,把寄存器想象成大脑的记忆,把堆栈想象成你桌子上需要处理的一堆文件。那么,您桌上当前正在使用其信息的书籍集可能被称为缓存,而您的库相当于DRAM。您确定要注册吗,请参阅Erics评论:“C#,”“volatile”不仅意味着“确保编译器和抖动不会对该变量执行任何代码重新排序或寄存器缓存优化”@MatthiasMüller:这适用于在寄存器中缓存值,而不是在寄存器中存储值。缓存值是存储在堆栈/堆上的值,暂时也保存在寄存器中。
volatile
几乎可以保证JIT不会使用寄存器来保存变量,因为无法保证不同的线程将在同一个内核上运行。因此,将变量声明为volatile将告诉编译器和JIT避免使用寄存器来修改变量的值。寄存器的使用在大多数体系结构中几乎是不可避免的,但是更改将写入内存以满足
volatile
约束。