Thanks, this was very helpful. If I understand correctly:

1. These ordering guarantees are part of the Go memory model? I couldn't 
find explicit descriptions of them in these pages:

https://golang.org/ref/mem
https://golang.org/pkg/sync/atomic/

2. The property that word-sized values are not subject to 
interleaving/tearing is an implementation detail, rather than a guarantee 
of the Go memory model?

On Monday, March 19, 2018 at 1:55:07 AM UTC-4, Ian Lance Taylor wrote:
>
> On Sun, Mar 18, 2018 at 9:47 PM, shivaram via golang-nuts 
> <golan...@googlegroups.com <javascript:>> wrote: 
> > 
> > I noticed that internally, the language implementation seems to rely on 
> the 
> > atomicity of reads to single-word values: 
> > 
> > 
> https://github.com/golang/go/blob/bd859439e72a0c48c64259f7de9f175aae3b9c37/src/runtime/chan.go#L160
>  
>
> In the machine level, words like "atomicity" are overloaded with 
> different meanings.  I think what you are saying is that the runtime 
> package is assuming that a load of a machine word will never read an 
> interleaving of two different store of a machine word.  It will always 
> read the value written by a single store, though exactly which store 
> it sees is unknown.  This is true on all the processors that Go 
> supports. 
>
>
> > As I understand it, this atomicity is provided by the cache coherence 
> > algorithms of modern architectures. Accordingly, the implementations in 
> > sync.atomic of word-sized loads (e.g., LoadUint32 on 386 and LoadUint64 
> on 
> > amd64) use ordinary MOV instructions: 
> > 
> > 
> https://github.com/golang/go/blob/bd859439e72a0c48c64259f7de9f175aae3b9c37/src/sync/atomic/asm_386.s#L146
>  
> > 
> > 
> https://github.com/golang/go/blob/bd859439e72a0c48c64259f7de9f175aae3b9c37/src/sync/atomic/asm_amd64.s#L103
>  
> > 
> > However, word-sized stores on these architectures use special 
> instructions: 
> > 
> > 
> https://github.com/golang/go/blob/bd859439e72a0c48c64259f7de9f175aae3b9c37/src/sync/atomic/asm_amd64.s#L133
>  
> > 
> > Given that the APIs being implemented don't provide any global ordering 
> > guarantees, what's the reason they can't be implemented solely with MOV? 
>
> You are not giving the correct reason for why atomic.LoadUint32 and 
> LoadUint64 can use ordinary MOV instructions on x86 processors.  The 
> LoadUint32, etc., functions guarantee much more than that they read a 
> value that is not an interleaving a multiple writes.  They are also 
> load-acquire operations, meaning that when the function completes, the 
> caller will see not only the value that was loaded but also all other 
> values that some other processor core wrote before writing to the 
> address being loaded (assuming the write was done using StoreUint32, 
> etc.).  It happens that on x86 you can implement load-acquire using a 
> simple MOV instruction.  Most other multicore processors use a more 
> complex memory model, and their sync/atomic implementations are 
> accordingly more complex. 
>
> Ian 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to