Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registers in C#

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.

like image 893
Matthias Müller Avatar asked Jun 13 '14 10:06

Matthias Müller


People also ask

What is static and register in C?

register is used to store the variable in CPU registers rather memory location for quick access. Static is used for both global and local variables. Each one has its use case within a C program. Extern is used for data sharing between C project files.

Is register used in C?

In the C programming language, register is a reserved word (or keyword), type modifier, storage class, and hint.

What is register in embedded C?

Many devices have multiple internal registers, but only respond to a single address. To access a specific register, the code first needs to write the register number to the device and then perform the required write/read operation. This is not difficult, but needs to be managed carefully.

What is register modifier in C?

The register modifier hints to the compiler that the variable will be heavily used and should be kept in the CPU's registers, if possible, so that it can be accessed faster.


2 Answers

"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.

like image 106
Guffa Avatar answered Nov 11 '22 15:11

Guffa


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.

like image 28
usr Avatar answered Nov 11 '22 15:11

usr