I just read an article. In my understanding, it states single word reads/writes in go are atomic, is it right?

162 views
Skip to first unread message

T L

unread,
Jul 6, 2016, 11:32:56 AM7/6/16
to golang-nuts
http://research.swtch.com/gorace
 

...  

The race is fundamentally caused by being able to observe partial updates to Go's multiword values (slices, interfaces, and strings): the updates are not atomic.

The fix is to make the updates atomic. In Go, the easiest way to do that is to make the representation a single pointer that points at an immutable structure. When the value needs to be updated, you allocate a new structure, fill it in completely, and only then change the pointer to point at it. This makes the assignment atomic: another goroutine reading the pointer at the same time sees either the new data or the old data, but not a mix, assuming the compiler is careful to read the pointer just once and then access both fields using the same pointer value. 

...



Jan Mercl

unread,
Jul 6, 2016, 11:38:46 AM7/6/16
to T L, golang-nuts
On Wed, Jul 6, 2016 at 5:33 PM T L <tapi...@gmail.com> wrote:

Certainly sized and/or certainly aligned memory writes are atomic on certain CPU architectures. But it is only the Go language specification and the Go memory model where guaranties one _may_ rely on [across architectures] are found.



--

-j

Axel Wagner

unread,
Jul 6, 2016, 11:38:58 AM7/6/16
to T L, golang-nuts
You are misreading this. a) it implicitly refers to a single architecture and b) it doesn't say that single-word accesses are atomic, it says that multi-word accesses are inherently non-atomic. Making it a single-word access is necessary but not sufficient, to actually get atomic reads/writes you need to use sync/atomic (and I don't understand why questions about which accesses are atomic keep coming up on golang-nuts and /r/golang and the like, when there exists a method that *gives* you atomic accesses in the best way possible for any given architecture).

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

T L

unread,
Jul 6, 2016, 11:55:04 AM7/6/16
to golang-nuts, tapi...@gmail.com


On Wednesday, July 6, 2016 at 11:38:58 PM UTC+8, Axel Wagner wrote:
You are misreading this. a) it implicitly refers to a single architecture and b) it doesn't say that single-word accesses are atomic, it says that multi-word accesses are inherently non-atomic.

I can't get the conclusion for a) from that article.

That article really imply (at least) pointers in go are atomic.

That article is written by Ross Cox.

Axel Wagner

unread,
Jul 6, 2016, 12:15:52 PM7/6/16
to T L, golang-nuts
I am aware who wrote that article (I read it a couple of years ago and even wrote an unsafe package based on it for fun, though never published it) and no, it doesn't imply that at all. It makes certain assurances for a particular compiler (gc) and a particular set of architectures (x86{,_64},…) at a certain point in time (long before even go1 was released).

To prove that it assumes both, you can try the races outlined in the article both with nacl (different architecture, same implementation) and gopherjs (different implementation) and will find out, that they don't work.

The fact of the matter is, Pointer/Single-word/Multi-word reads/writes are neither atomic, nor are they not atomic. It's simply undefined whether they are. It *is* however defined, that the sync/atomic package provides atomic accesses and to reiterate, you can trust, that it will give you the best way to implement atomic store/loads/cas/whatever on every architecture and in every implementation possible (otherwise you should file a bug). So, again, I don't see why there is even the question of whether certain accesses are atomic or not, when there is zero disadvantage to just use the package that gives you those guarantees.

Konstantin Khomoutov

unread,
Jul 6, 2016, 12:47:52 PM7/6/16
to T L, golang-nuts
On Wed, 6 Jul 2016 08:55:03 -0700 (PDT)
T L <tapi...@gmail.com> wrote:

>
>
> On Wednesday, July 6, 2016 at 11:38:58 PM UTC+8, Axel Wagner wrote:
> >
> > You are misreading this. a) it implicitly refers to a single
> > architecture and b) it doesn't say that single-word accesses are
> > atomic, it says that multi-word accesses are inherently non-atomic.
> >
>
> I can't get the conclusion for a) from that article.
>
> That article really imply (at least) pointers in go are atomic.

Please consider reading [1, 2] to get a rough overview of what can go
wrong about word-sized loads/stores etc. While the articles mostly
talk about C and C++, Go's stance on atomicity are the same -- the only
thing about sharing memory its specification actually codifies is those
"happens-before" relations which are at a level above "the metal" and
boil down to a simple thing: you either use implicit synchronization
(channels) or explicit (mutexes) or explicitly use atomic operations
on shared memory using the sync/atomic package, and then you're safe.
Any other non-synchronized memory access is undefined behaviour and
renders your program incorrect (as in "anything can happen").

[3] is a must read as well.

1. http://preshing.com/20130618/atomic-vs-non-atomic-operations/
2. http://preshing.com/20120515/memory-reordering-caught-in-the-act/
3. https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong
Reply all
Reply to author
Forward
0 new messages