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.