This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: More on memory barriers
On Wed, Sep 15, 2004 at 11:43:32AM -0400, Jason Merrill wrote:
> > Well, no, Alpha needs
> >
> > read_memory_barrier ();
> > if (!initialized)
> >[...]
>
> Hmm? Why do we need the read barrier on the initialization path? I would
> expect the mutex to provide enough of a read barrier.
This is *exactly* what the messages you pasted at me the other day
were explaining. Go back and re-read them.
Specifically, cacheline flush requests from other processors are
not necessarily honored immediately and are not synchronized with
loads. So you can get a situation in which a load is satisfied
from a cacheline that, from the viewpoint of the rest of the
system, is out of date. Using a memory barrier causes the
cacheline probe queue to be emptied.
As far as I know, Alpha EV6 is unique in this desynchronization.
Other processors will either honor the cache probe immediately,
or stall the load if it hits a cacheline in the queue.
> >> On ia64, does a release barrier have the desired semantics, or do we
> >> need a full barrier?
...
> By "release barrier" I meant annotating the assignment to initialized with
> .rel, which I would expect to be less expensive than __sync_synchronize.
> But you would know better than I.
No. You need ordering between the constructor and the setting
of initialize. Release semantics on stores happen *after* the
store. There is no st.acq for getting a barrier before a store,
so in order to get a barrier before, we must use "mf".
Ideally, we'd have a peephole that turned
st random unrelated stuff
mf
=>
st.rel random unrelated stuff
As far as I know, "mf" is no more expensive that that -- just another
instruction on the stream. All barriers, .rel, .acq, mf, are equivalent
strength, just the encoding and logical placement differs.
r~