Re: Am I or Alexandrescu wrong about singletons?
On Mar 29, 7:45 am, "Leigh Johnston" <le...@i42.co.uk> wrote:
"James Kanze" <james.ka...@gmail.com> wrote in
messagenews:ddf75ee4-b26b-46a0-af32-99ce34954669@k19g2000yqn.googlegroups.com...
On Mar 26, 12:25 am, "Leigh Johnston" <le...@i42.co.uk> wrote:
"George Neuner" <gneun...@comcast.net> wrote in message
news:rq1nq5tskd51cmnf585h1q2elo28euh2kn@4ax.com...
<snip>
'volatile' is necessary for certain uses but is not
sufficient for (al)most (all) uses. I would say that for
expert uses, some are portable and some are not. For
non-expert uses ... I would say that most uses
contemplated by non-experts will be neither portable nor
sound.
Whether or not the store that is guaranteed to be emitted
by the compiler due to the presence of volatile propagates
to L1 cache, L2 cache or main memory is irrelevant as far
as volatile and multi-threading is concerned as long as CPU
caches remain coherent.
That depends on the architecture and what the compiler
actually does in the case of volatile. Some of the more
recent processors have a separate cache for each core, at
least at the lowest level, and most access memory through a
pipeline which is unique to the core.
You could argue that because of this volatile is actually
more useful for multi-threading than for its more
traditional use of performing memory mapped I/O with modern
CPU architectures.
You'll have to explain that, since none of the compilers I
use generate any sort of fence or membar when volatile is
used, and the processors definitely require it,
I would expect the following property of the volatile keyword
on VC++ to be a common interpretation of the semantics of
volatile for most C++ compilers:
"Objects declared as volatile are not used in certain
optimizations because their values can change at any time. The
system always reads the current value of a volatile object at
the point it is requested, even if a previous instruction
asked for a value from the same object. Also, the value of the
object is written immediately on assignment. "
That's generally the case. For some very imprecise meaning of
"reads" and "writes". On the compilers I have access to, the
meaning is no more than "executes a machine level load or store
instruction". Which is practically meaningless for anything
useful on a modern processor.
It should be obvious how this property can be useful when
writing multi-threaded code, not always useful in isolation
perhaps but certainly useful when used in conjunction with
other threading constructs such as mutexes and fences.
It isn't, at least not to me. Perhaps if you could come up with
a small example of where it might be useful.
Depending on the compiler/platform and on the actual use-case
volatile on its own might not be enough: from what I can tell
VC++ volatile does not emit fence instructions for x86 yet the
above property still stands (and there are rare cases when
memory barriers are needed on x86,
seehttp://bartoszmilewski.wordpress.com/2008/11/05/who-ordered-memory-fe...).
I agree that this is mostly an implementation specific issue
and the current C++ standard is threading agnostic however
saying volatile has absolutely no use in multi-threading
programming is incorrect.
Given that the exact semantics volatile and threading are not
really covered by the standard, it's certain that one cannot
make blanket claims: an implementation could define volatile in
a way that would make it useful with its implementation of
threading, say by giving volatile the same meaning that it has
in Java, for example. In practice, however, Posix doesn't, and
I don't know of a compiler under Unix which goes beyong the
Posix guarantees (except when assembler is involved, and then
they give enough guarantees that you don't need volatile). And
while I've yet to find an exact specification for Windows, the
implementation of volatile in VC++ 8.0 doesn't do enough to make
it useful in threading, and Microsoft (in the voice of Herb
Sutter) has said here that it isn't useful (although I don't
know if Herb is speaking for Microsoft here, or simply
expressing his personal opinion).
Anyhow, for the moment, all I can really claim is that it is
useless under the Unix I know (Solaris, HP/UX, AIX and Linux)
and under Windows.
Performance is often cited as another reason to not use
volatile however the use of volatile can actually help with
multi-threading performance as you can perform a safe
lock-free check before performing a more expensive lock.
Again, I'd like to see how. This sounds like the double-checked
locking idiom, and that's been proven not to work.
I agree with what Andy said elsewhere in this thread:
"Is volatile sufficient - absolutely not.
Portable - hardly.
Necessary in certain conditions - absolutely."
Yes, but Andy didn't present any facts to back up his statement.
The simplest solution would be to just post a bit of code
showing where or how it might be useful. A good counter example
trumps every argument.
--
James Kanze
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]