Answering this question made me think about something is still not clear for me. Let\'s first assume we read all from this post and this post.
[begin edit] Mayb
This question is very confusing. Let me try to break it down.
Are volatile variables useful?
Yes. The C# team would not have added a useless feature.
If yes then when?
Volatile variables are useful in certain highly performance-sensitive multithreaded applications where the application architecture is predicated on sharing memory across threads.
As an editorial aside, I note that it should be rare for normal line-of-business C# programmers to be in any of these situations. First, the performance characteristics we are talking about here are on the order of tens of nanoseconds; most LOB applications have performance requirements measured in seconds or minutes, not in nanoseconds. Second, most LOB C# applications can do their work with only a small number of threads. Third, shared memory is a bad idea and a cause of many bugs; LOB applications which use worker threads should not use threads directly, but rather use the Task Parallel Library to safely instruct worker threads to perform calculations, and then return the results. Consider using the new await
keyword in C# 5.0 to facilitate task-based asynchrony, rather than using threads directly.
Any use of volatile in a LOB application is a big red flag and should be heavily reviewed by experts, and ideally eliminated in favour of a higher-level, less dangerous practice.
lock will prevent instruction reordering.
A lock is described by the C# specification as being a special point in the code such that certain special side effects are guaranteed to be ordered in a particular way with respect to entering and leaving the lock.
volatile because will force CPU to always read value from memory (then different CPUs/cores won't cache it and they won't see old values).
What you are describing is implementation details for how volatile could be implemented; there is not a requirement that volatile be implemented by abandoning caches and going back to main memory. The requirements of volatile are spelled out in the specification.
Interlocked operations perform change + assignment in a single atomic (fast) operation.
It is not clear to me why you have parenthesized "fast" after "atomic"; "fast" is not a synonym for "atomic".
How lock will prevent cache problem?
Again: lock is documented as being a special event in the code; a compiler is required to ensure that other special events have a particular order with respect to the lock. How the compiler chooses to implement those semantics is an implementation detail.
Is it implicit a memory barrier in a critical section?
In practice yes, a lock introduces a full fence.
Volatile variables can't be local
Correct. If you are accessing a local from two threads then the local must be a special local: it could be a closed-over outer variable of a delegate, or in an async block, or in an iterator block. In all cases the local is actually realized as a field. If you want such a thing to be volatile then do not use high-level features like anonymous methods, async blocks or iterator blocks! That is mixing the highest level and the lowest level of C# coding and that is a very strange thing to do. Write your own closure class and make the fields volatile as you see fit.
I read something from Eric Lippert about this but I can't find that post now and I don't remember his answer.
Well I don't remember it either, so I typed "Eric Lippert Why can't a local variable be volatile" into a search engine. That took me to this question:
why can't a local variable be volatile in C#?
Perhaps that is what you're thinking of.
This makes me think they're not implemented with an Interlocked.CompareExchange() and friends.
C# implements volatile fields as volatile fields. Volatile fields are a fundamental concept in the CLR; how the CLR implements them is an implementation detail of the CLR.
in what they're different?
I don't understand the question.
What volatile modifier will do for example in this code?
++_volatileField;
It does nothing helpful, so don't do that. Volatility and atomicity are completely different things. Doing a normal increment on a volatile field does not make the increment into an atomic increment.
Moreover what compiler (beside warnings) will do here:
The C# compiler really ought to suppress that warning if the method being called introduces a fence, as this one does. I never managed to get that into the compiler. Hopefully the team will someday.
The volatile field will be updated in an atomic manner. A fence will be introduced by the increment, so the fact that the volatile half-fences are skipped is mitigated.
How is it possible for non volatile fields?
That's an implementation detail of the CLR.
Does they imply barriers too?
Yes, the interlocked operations introduce barriers. Again, this is an implementation detail.
Doesn't this hurt performance a lot (compared to volatile)?
First off, comparing the performance of broken code to working code is a waste of time.
Second, if you do feel like wasting time, you are perfectly capable of measuring the performance of each yourself. Write the code both ways, get out a stopwatch, run it a trillion times each way, and you'll know which is faster.
If volatile doesn't imply barriers but others do then why we can't use them as on local variables?
I can't even begin to make sense of this question.