The implementation of Volatile.Read
merely inserts a memory barrier after the read:
public static int Read(ref int location)
{
var value = location;
Thread.MemoryBarrier();
return value;
}
Thus, usage of the method like so...
return Volatile.Read(ref _a) + Volatile.Read(ref _b);
...would be equivalent to:
var a = _a;
Thread.MemoryBarrier();
var b = _b;
Thread.MemoryBarrier();
return a + b;
Given the above, wouldn't the resulting behavior be identical if the parameter was not a ref
?
public static int Read(int value)
{
Thread.MemoryBarrier();
return value;
}
I guess that the ref
parameter was used simply to prevent programmers from passing things other than variables, such as Volatile.Read(2 + 3)
. Can anyone see any other reason for the ref
when variables are passed in?
That is not what the real code looks like after the jitter is done with it. Volatile.Read() is an intrinsic. An expensive word that means that the jitter will not compile the method at all but substitutes it with a processor-specific version of the machine code. The code you found is just a place-holder that could serve as a fallback on a machine without a decent jitter. Theoretically.
You can see what you get on your machine with Debug > Windows > Disassembly. You have to switch to the Release build and use Tools > Options > Debugging > General > untick "Suppress JIT optimization". Most programmers will be happy with what they see:
04CF0450 mov ecx,dword ptr ds:[7C43ACh]
Or in other words: nothing. Just a plain memory read without a barrier. Intel/AMD cores have a strong memory model that doesn't require a barrier. But, say, an ARM core does and will need the address of the variable. Itanium was also weak, but its jitter was discontinued.
Do note how, while you could be happy, that this is also rather bad news. You basically can't rely on testing your program on your dev machine and conclude it is good enough. Or in other words, no way to tell that you should have used Volatile but you forgot. Only running your program on the device is going to give you a hint that you got it wrong. It does take a lot of courage to skip lock
:)
Several more intrinsics around like that, Math.Sqrt() for example. Most processors have it as a built-in machine code instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With