On Wednesday, September 14, 2016 at 2:58:24 AM UTC+8, Henrik Johansson 
wrote:
>
> I think this will be an interesting read especially if you come from Java. 
>
> https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/
>

There were some surprises in there! With a bit more perspective I can see 
that my criticisms of the other data race article in this thread were 
grounded in an "ideal" reality, where the compiler exists solely to provide 
a good user experience to programmers. eg. via abstractions that don't leak 
details about the underlying machine's memory semantics, or verifying that 
an optimisation's prerequisites actually hold before applying it.

Of course the reality we inhabit includes compilers which are blind to data 
races, since a data race is defined by their language spec as causing 
undefined behaviour. It's mildly unfortunate that a program containing 
undefined behaviour is allowed to compile (tip of the hat to rust for going 
the extra mile here), but with C inhabiting a space intentionally close to 
the machine and having a long history prior to threads becoming widely used 
it is understandable.

Thanks everyone for helping me learn! If you'll humour me a moment longer, 
I'm curious about the atomic.Value approach. If you have a single writer:

newMap := make(map[int]int)
newMap[4] = 2
newMap[9] = 3
x.myMap.Store(newMap) //x.myMap is an atomic.Value

And a reader:

table := x.myMap.Load().(map[int]int)
fmt.Println(table[9])

Does go's memory model ensure that the read of table[9] sees the value the 
writer put there (as long as the Load happens after the Store)?

If so, how does the compiler/runtime know that table[9] is a shared memory 
location requiring properly publishing when it hasn't been explicitly 
involved in any kind of barrier operation?

If the writer/reader use a channel instead of atomic.Value, does it change 
anything? ie.

x.myMap = newMap //x.myMap is a map[int]int
x.changed <- nil

<-x.changed
table := x.myMap
fmt.Println(table[9])

I guess in this case the scheduler could arrange for the reader to run on 
the same processor as the writer did and avoid worrying about cache 
inconsistencies? But I also see an opportunity here for the writer to 
update the map again, after the reader has received on the channel but 
before it has read from x.myMap. Which means the read could see the second 
update to the map whose underlying hashtable may not be in a consistent 
state when observed by the reader?

(the sensible thing would be to send the map over the channel, but for the 
purpose of thought experiment...)
-sqweek

-- 
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