[cpp-threads] memory model
Peter Dimov
pdimov at mmltd.net
Sun May 1 16:15:54 BST 2005
Doug Lea wrote:
> But to get back to the main point, the basic question here is,
> Do these special msync forms describe properties that are already in
> the code itself? If so, someday those forms will seem just
> as quaint as "register" qualifiers.
>
> Or, in other words, are there cases where a sufficiently good
> optimizer that did not use the special forms would NOT be able to
> weaken a barrier because of upcoming dependent loads, etc?
I can think of no interesting cases where an optimizer can turn acq into
ddacq or ccacq.
A ccacq or ddacq gives the optimizer permission to weaken the barrier,
permission that the ordinary acquire does not grant.
The optimizer is simply not allowed to not honor the acquire and weaken it.
Consider:
if( int * p = atomic_load_acq( &x ) )
{
f( *p );
}
g( y );
The acquire forces the compiler to insert a barrier that prevents the read
from y to migrate above the load.
if( int * p = atomic_load_ddacq( &x ) )
{
f( *p );
}
g( y );
The ddacq grants the compiler freedom to not concern itself with the
non-dependent read from y and only deal with the read from *p, if necessary
(on Alpha, for example.)
This maps well to hardware because most CPUs already track these
dependencies.
In Sparc-like terms, load_acq is
load
#LoadLoad | #LoadStore
load_ccacq is
load
#LoadLoad
because control-dependent stores are implicitly ordered, and load_ddacq is
load
because data-dependent accesses are implicitly ordered.
(I hope I got these right.)
More information about the cpp-threads
mailing list