Re: When is "volatile" used instead of "lock" ?
- From: Jon Skeet [C# MVP] <skeet@xxxxxxxxx>
- Date: Tue, 10 Jul 2007 07:52:39 +0100
Peter Ritchie [C#MVP] <prsoco@xxxxxxxxxxxxxxxxx> wrote:
"Jon Skeet [C# MVP]" <skeet@xxxxxxxxx> wrote in message
news:MPG.20fcde81604c43b12c5@xxxxxxxxxxxxxxxxxxxxxxx
Well, that's not caching (which would be an *earlier* read) - it's
delaying.
Maybe a poor choice of an overload term, but I did say "compiler from having
optimized use a member by caching it to a register".
True,.
However, I've just reread the spec, and it doesn't just say
that *writes* can't be moved past a volatile write - it says that *no*
memory references can move to later than a volatile write or earlier
than a volatile read.
...with regard to "acquire semantics" and "release semantics". So 12.6.7
make sense with regard only to processor cachings. Everything I've read
discusses "acquire semantics" and "release semantics" only in the context of
processor caching, not compiler (JIT or otherwise) optimizations.
Once again, there's nothing in the spec which distinguishes the two.
Yes, a lot of pages describing the details go into more detail about
different CPU architectures, but please say where in the spec it says
"You can't rely on any of this as the overall semantics of the program,
because the JIT and the CPU are separate."
The JIT needs to take account of what CPU it's running on in order to
make sure that the overall semantics are correct, that's all.
http://msdn2.microsoft.com/EN-US/library/aa490209.aspx
Discusses the acquire semantics of specific Win32 functions, nothing to do
with compiler optimizations and no existing native compiler I know of
changes it's optimization behaviour in the presence of those Interlocked
functions.
http://msdn2.microsoft.com/en-us/library/ms686355.aspx
Details that prior to VC 2003 "volatile" had no acquire/release semantics
and only dealt with compiler optimizations.
You shouldn't try to reason about the CLR term "volatile" with
reference to what it means outside the CLI, in my view.
If you take 12.6.7 para 2's "after any memory references" to mean anything
other than processor cachings, as soon as you introduce Monitor.Enter or
Monitor.Exit (or volatile) you can't optimize anything, even locals. That's
clearly not the intention of that paragraph. That paragraph says almost the
same thing as Joe's blog with respect to st.rel and ld.acq, which only
applies to processor caching. That paragraph is the only place 335 doesn't
associate the volatile. prefix when it talks about what volatile reads and
writes do. There's the almost casual mention of Enter and Exit being an
implicite volatile read and write respectively; but that also makes perfect
sense if you're only discussing processor caching.
But if you don't read the spec as overall semantics, it's entirely
useless.
Relating to origins, the C++ volatile keyword in VC++ never dealt with
acquire or release semantics until VC++ 2005. Prior to that, for the past
30+ years it has been used only to tell the compiler not to optimize that
identifier.
Yup - but again, that doesn't alter what the spec says.
It's not a huge stretch to think of 335:12.6 only in the context of
processor caching.
That's where we disagree. I believe that if the spec says that X will
happen and Y doesn't happen, then if I can show Y happening and X not
happening on a particular implementation, then that implementation is
*broken* - it doesn't conform with the spec.
<snip>
It can't occur within the spec either though. That's moving one write
(the one to memberVariable) to *after* the lock is released. That's
prohibited.
Only if you make the leap that "acquire semantics" and "release semantics"
don't refer to anything other than processor caching.
No - I'm saying they refer to the overall effect - that you should view
the spec as an absolute in terms of what's allowed to occur and what's
not, regardless of how that's achieved.
The spec make complete sense if all it's talking about is processor
caching with regard to acquire/relese semantics. The processor does
reorder memory accesses, and similar to Joe's blog, in relation to
the instruction stream. The mere mention of the CIL instruction
sequence in 335 doesn't imply that
If any CLI implementation allows the processor to reorder instructions
in a way which means that 12.6.7 can't be relied upon for visible
effects, that implementation is broken.
Did you read the section of Grant's page about the locking protocol, by
the way?
--
Jon Skeet - <skeet@xxxxxxxxx>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
.
- Follow-Ups:
- Re: When is "volatile" used instead of "lock" ?
- From: Peter Ritchie [C#MVP]
- Re: When is "volatile" used instead of "lock" ?
- From: Jon Skeet [C# MVP]
- Re: When is "volatile" used instead of "lock" ?
- References:
- Re: When is "volatile" used instead of "lock" ?
- From: Peter Ritchie [C#MVP]
- Re: When is "volatile" used instead of "lock" ?
- From: Jon Skeet [C# MVP]
- Re: When is "volatile" used instead of "lock" ?
- From: Peter Ritchie [C#MVP]
- Re: When is "volatile" used instead of "lock" ?
- From: Jon Skeet [C# MVP]
- Re: When is "volatile" used instead of "lock" ?
- From: Peter Ritchie [C#MVP]
- Re: When is "volatile" used instead of "lock" ?
- Prev by Date: Re: VS2005 <-> VSS2005
- Next by Date: Re: Reading DateTime table from mdb file with C#
- Previous by thread: Re: When is "volatile" used instead of "lock" ?
- Next by thread: Re: When is "volatile" used instead of "lock" ?
- Index(es):
Relevant Pages
|