Why does Volatile.Read accept a ref parameter?

The Volatile.Read implementation simply inserts a memory barrier after reading:

 public static int Read(ref int location) { var value = location; Thread.MemoryBarrier(); return value; } 

So using this method ...

 return Volatile.Read(ref _a) + Volatile.Read(ref _b); 

... will be equivalent to:

 var a = _a; Thread.MemoryBarrier(); var b = _b; Thread.MemoryBarrier(); return a + b; 

Given the above, would the resulting behavior not be identical if the parameter was not ref ?

 public static int Read(int value) { Thread.MemoryBarrier(); return value; } 

I assume that the ref parameter was used simply to prevent programmers from passing things other than variables, like Volatile.Read(2 + 3) . Can anyone see any other reason for ref when variables are being passed?

+5
source share
2 answers

This is not what the real code looks like after a shiver is made with it. Volatile.Read () is internal. An expensive word, which means that jitter will not compile the method at all, but replaces it with a version of machine code on a specific processor. The code you found is just the owner of the place, which can serve as a reserve on the machine without a decent jitter. In theory.

You can see what you get on your computer using Debug> Windows> Disassembly. You need to switch to the Release build and use "Tools"> "Options"> "Debug"> "General"> "Cancel JIT Optimization". Most programmers will be happy with what they see:

 04CF0450 mov ecx,dword ptr ds:[7C43ACh] 

Or in other words: nothing. Just ordinary memory is read without a barrier. Intel / AMD cores have a strong memory model that does not require a barrier. But, say, the ARM core does and will need the address of a variable. Itanium was also weak, but its trembling was stopped.

Remember, as long as you can be happy, this is also pretty bad news. Basically, you cannot rely on testing your program on your dev machine and complete it well enough. Or, in other words, in no way say that you should have used Volatile, but you forgot. Only starting your program on the device will give you a hint that you are wrong. To skip the lock :), you need a lot of courage:

Several other intrigues like this are Math.Sqrt (), for example. Most processors have it as a built-in machine code instruction.

+9
source

Because .NET arguments are passed by default by value.

0
source

Source: https://habr.com/ru/post/1268048/


All Articles