开发者

C# - Is "volatile" really needed as a keyword?

As I read deeper and deeper into the meaning of the volatile keyword, I keep saying to myself "this is way into implementation, this should not be a part of a high level programming languag开发者_JS百科e".

I mean, the fact that CPUs cache the data should be interesting for the JIT compiler, not to the C# programmer.

A considerable alternative might be an attribute (say, VolatileAttribute).

What do you think?


I think you got side-tracked. All the tech stuff about caching etc is part of an attempt to explain it in low level terms. The functional description for volatile would be "I might be shared". Given that by default nothing can be shared between threads, this is not altogether strange. And I think fundamental enough to warrant a keyword over an attribute, but I suppose it was largely influenced by historic decisions (C++)

One way to replace/optimize it is with VolatileRead() and VolatileWrite() calls. But that's even more 'implementation'.


Well, I certainly agree, it is pretty horrible that such an implementation detail is exposed. It is however the exact same kind of detail that's exposed by the lock keyword. We are still very far removed from that bug generator to be completely removed from our code.

The hardware guys have a lot of work to do. The volatile keyword matters a lot of CPU cores with a weak memory model. The marketplace isn't been kind to them, the Alpha and the Itanium haven't done well. Not exactly sure why, but I suspect that the difficulty of writing solid threaded code for these cores has a lot to do with it. Getting it wrong is quite a nightmare to debug. The verbiage in the MSDN Library documentation for volatile applies to these kind of processors, it otherwise is quite inappropriate for x86/x64 cores and makes it sound that the keyword is doing far more than it really does. Volatile merely prevents variable values from being stored in CPU registers on those cores.

Unfortunately, volatile still matters on x86 cores in very select circumstances. I haven't yet found any evidence that it matters on x64 cores. As far as I can tell, and backed up by the source code in SSCLI20, the Opcodes.Volatile instruction is a no-op for the x64 jitter, changing neither the compiler state nor emitting any machine code. That's heading the right way.

Generic advice is that wherever you're contemplating volatile, using lock or one of the synchronization classes should be your first consideration. Avoiding them to try to optimize your code is a micro-optimization, defeated by the amount of sleep you'll lose when your program is exhibiting thread race problems.


Using an attribute would be acceptable, if it were the other way around, that is, the compiler would assume that all varaibles are volatile, unless explicitly marked with an attribute saying it was safe. That would be incredibly determental to performance.

Hence it's assumed that, since having a variable's value changed outside of the view of the compiler is an abberation, the compiler would assume that it is not happeing.

However, That could happen in a program so the language itself must have a way of showing that.

Also, you seems confused about "implementation details". The term refers to things the compiler does behind your back. This is not the case here. Your code is modifying a varaible outside of the view of the compiler. SInce it's in your code, it will always be true. Hence the langauge must be able to indicate that.


volatile in c# emits the correct barriers, or fences, which would matter to the programmer doing multi-thread work. Bear in mind, that the compiler, runtime, and the processor all can reorder reads/writes to some degree (each has its own rules). Though CLR 2.0 has a stronger memory model that what CLI ECMA specifies, the CLR memory model still is not the strictest memory model so you have a need for volatile in C#.

As an attribute, I don't think you can use attributes inside a method body, so the keyword is necessary.


IIIRC, in C++ volatile was mainly about memory mapped I/O rather than cache. If you read the same port twice you get different answers. Still, I would agree with your assessment that this is more cleanly expressed in C# as an attribute.

On the other hand, most actual uses of volatile in C# can better be understood as thread lock anyway, so the choice of volatile is may be a little unfortunate.

Edit: Just to add: two links to show that in C/C++ `volatile is explicitly not for multithreading.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜