问题
we all know the idea of stack and heap, but I recently read about a third option to save data: registers.
I have a hard time finding good articles about this type, what I found was: http://www.dotnetperls.com/method-parameter, and a lot of stuff for C, for example: http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
The only real informations I have so far: every CPU has its own registers, which can be used to save data, which is accessed at the fastest way possible, for example in the for loops.
As far as I've seen, this en-registering is made by the CLR. Then I remembered this volatile-keyword, and if we look at MSDN:
The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.
So does the Volatile exactly that? It tells the CLR not to use the CPU register but the stack/heap, which can be accesses by all CPUs/threads?
I'm sorry for my confusing question, but there is really little information on this topic around.
回答1:
"Every CPU has his own Register"
Every CPU has a set of registers, that are used for most operations that involve any data. Typically an instruction loads some data from memory into a register, then another instruction does some calculations on the data in the register.
The CPU has a few registers that are intended for data, some that are intended for pointers, and some special registers that keep track of program execution like the instruction pointer, the stack pointer and the flags register.
As the CPU has several registers, the JIT compiler can sometimes use a few of them as storage for local variables. Instead of allocating the variable on the stack, the register is dedicated to hold the value of the variable.
The volatile
keyword doesn't affect how registers can be used for storage. If a variable can be accessed by different threads, then it's not the kind of variable that is a candidate to be stored in a register. In practive, it's just local variables with a limited scope and short life span that will be stored in registers.
回答2:
That sentence is misleading in the sense that it is not a precise definition of what volatile guarantees. Volatile is not specified in terms of compiler optimizations. Also, restricting the compiler is not enough on ARM. The CPU must be restricted as well. I suggest you research what volatile guarantees exactly.
It is not even true that volatile prevents the use of registers. Volatile loads guarantee that the volatile variable is being read exactly as often as the program does it and in the same order.
When you write:
volatile int sharedVar = 0;
Console.WriteLine(sharedVar);
Console.WriteLine(sharedVar);
The JIT must read exactly two times. But it can still use registers to store the values read.
If the CLR can prove that sharedVar
is never written to and always will have the value 0
it can even delete the reads. It probably has to insert memory barriers in some places instead of the reads because volatile
accesses have certain ordering guarantees. But no load has to physically happen at all. (The current JIT does not do this optimization.)
Registers are an implementation detail. The CLR is not specified in terms of physical implementation. I understand you want to know about implementation details and that's fine. They do not matter much for what the CLR guarantees the programmer, though.
来源:https://stackoverflow.com/questions/24203679/registers-in-c-sharp