In the example I provided the essential point is that
there
is *one* *correct* access pattern which is to read it once
for each call to f(), to ensure that the same value is used
everywhere in that function. Declaring this value volatile
and taking a local copy does exactly the right thing.
The alternative would be protect it by a mutex for as long
as f() runs. For no good reason, as I don't mind it being
overwritten while f() runs. Would that be more 'optimal' ?
Ah. pthread_mutex_lock() / unlock(), as EXTERNAL functions, will never
be optimized away or inlined. Now, being all sequence points, if you
simply do
pthread_mutex_lock();
xval = x;
pthread_mutex_unlock();
the compiler is not allowed to move statements out the locked section
or reorder them in any way (without need for any volatile qualifiers).
http://en.wikipedia.org/wiki/Sequence_point
(or the C89 standard). This is another point that people forget --
many reorderings that they wish to prohibit using volatile are already
prohibited by the "sequence point theory".
In fact, I think the optimization you fear might not be allowed by
sequence points, even without any mutex calls (or volatiles) at all --
depending on your actual code.
OK, even if
your disk thread is periodic for some reason, how does
that argue for library-level synchronization, *instead of* app-level
synchronization? In this case the cost would be the same -- no loss.
I don't see the point.
You initially replied to my advice to not do any sync at *lib-level*
(jack/ringbuffer.h), and leave sync up to the app (whoever includes
jack/ringbuffer.h). But we're splitting hairs now.
No, I'm talking about SMP systems. Writing the
data and updating
the write pointer is done by the same thread and hence CPU, these
actions won't be re-ordered.
I see. But as I said, in general the cache coherency problem is worse
than the pipeline reordering problem -- i.e. when there are multiple
CPUs/cores using different caches, they may see actions out-of-order.
"Intel
and AMD" only?
There is no legal obligation for code to be portable. Nor is there
any moral obligation. If I choose to support only Intel and AMD PCs
and not embedded systems or mobile devices (and for the kind of SW
I write that does make sense) then that is my choice, period.
Your call. Still, don't forget that x86 != AMD + Intel -- there are
also VIAs, and others. I don't really know how widespread they are in
"PCs", or what guarantees they offer. I also don't know if your
non-reordering assumption (for which I haven't really seen any hard
documentation -- though I've heard rumours too) applies to Intel
Atom's, AMD Geode's etc (some of which may be in netbooks, OLPC etc).
waving their finger about programming style etc. There
is room for
some pragmatism in everything.
OK... This thread's subject is about programming advice though :)
Plus, when there is no big cost to doing things "by the book", I think
developers should be encouraged to keep their code portable, at least
in order to save the world future pains a-la Y2K etc.
-- Dan