Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not volatile on System.Double and System.Long?

A question like mine has been asked, but mine is a bit different. The question is, "Why is the volatile keyword not allowed in C# on types System.Double and System.Int64, etc.?"

On first blush, I answered my colleague, "Well, on a 32-bit machine, those types take at least two ticks to even enter the processor, and the .Net framework has the intention of abstracting away processor-specific details like that." To which he responds, "It's not abstracting anything if it's preventing you from using a feature because of a processor-specific problem!"

He's implying that a processor-specific detail should not show up to a person using a framework that "abstracts" details like that away from the programmer. So, the framework (or C#) should abstract away those and do what it needs to do to offer the same guarantees for System.Double, etc. (whether that's a Semaphore, memory barrier, or whatever). I argued that the framework shouldn't add the overhead of a Semaphore on volatile, because the programmer isn't expecting such overhead with such a keyword, because a Semaphore isn't necessary for the 32-bit types. The greater overhead for the 64-bit types might come as a surprise, so, better for the .Net framework to just not allow it, and make you do your own Semaphore on larger types if the overhead is acceptable.

That led to our investigating what the volatile keyword is all about. (see this page). That page states, in the notes:

In C#, using the volatile modifier on a field guarantees that all access to that field uses VolatileRead or VolatileWrite.

Hmmm.....VolatileRead and VolatileWrite both support our 64-bit types!! My question, then, is,

"Why is the volatile keyword not allowed in C# on types System.Double and System.Int64, etc.?"

like image 391
lmat - Reinstate Monica Avatar asked Jan 18 '11 17:01

lmat - Reinstate Monica


People also ask

Why would you declare a field as volatile?

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.

Why is volatile Not enough?

Volatile is a compiler keyword that tells the compiler what to do. It does not necessarily translate into (essentially) bus operations that are required for atomicity. That is usually left up to the operating system. Edit: to clarify, volatile is never enough if you want to guarantee atomicity.


2 Answers

He's implying that a processor-specific detail should not show up to a person using a framework that "abstracts" details like that away from the programmer.

If you are using low-lock techniques like volatile fields, explicit memory barriers, and the like, then you are entirely in the world of processor-specific details. You need to understand at a deep level precisely what the processor is and is not allowed to do as far as reordering, consistency, and so on, in order to write correct, portable, robust programs that use low-lock techniques.

The point of this feature is to say "I am abandoning the convenient abstractions guaranteed by single-threaded programming and embracing the performance gains possible by having a deep implementation-specific knowledge of my processor." You should expect less abstractions at your disposal when you start using low-lock techniques, not more abstractions.

You're going "down to the metal" for a reason, presumably; the price you pay is having to deal with the quirks of said metal.

like image 188
Eric Lippert Avatar answered Oct 02 '22 21:10

Eric Lippert


Yes. Reason is that you even can't read double or long in one operation. I agree that it is poor abstraction. I have a feeling that reason was that reading them atomically requires effort and it would be too smart for compiler. So they let you choose the best solution: locking, Interlocked, etc.

Interesting thing is that they can actually be read atomically on 32 bit using MMX registers. This is what java JIT compiler does. And they can be read atomically on 64 bit machine. So I think it is serious flaw in design.

like image 20
Andrey Avatar answered Oct 02 '22 22:10

Andrey