Live data from Hacker News

Are Go maps sensitive to data races?

dave.cheney.net

71–80 of 81 posts

Re: Are Go maps sensitive to data races?

#71
post #64

Earlier quoted context omitted.

So... the second thread needs to wait for the GC in order to modify the map concurrently? I mean, it is an optimization for the most common case (single-threaded access), but it imposes a quite high penalty for concurrent access... Although I could imagine a similar "signaling" mechanism, where each thread would periodically read a single snychronized variable, to check if there's any additional "re-synchronisation"…

> So... the second thread needs to wait for the GC in order to modify the map concurrently? No nobody needs to wait for a GC, but we use the same mechanism that the GC does. > Although I could imagine a similar "signaling" mechanism, where each thread would periodically read a single synchronised variable And that's how the GC already works. Except instead of a variable normally a 'test' instruction is used on a page…

> Except instead of a variable normally a 'test' instruction is used on a page of memory, and instead of setting the variable, the permission on the page are changed triggering a page fault.

Which GCs do that? The only one I know is Azul's Pauseless JVM GC, but that's a kind of a special case, given that it needs support from the kernel.

Re: Are Go maps sensitive to data races?

#72
post #71

Earlier quoted context omitted.

> So... the second thread needs to wait for the GC in order to modify the map concurrently? No nobody needs to wait for a GC, but we use the same mechanism that the GC does. > Although I could imagine a similar "signaling" mechanism, where each thread would periodically read a single synchronised variable And that's how the GC already works. Except instead of a variable normally a 'test' instruction is used on a page…

> Except instead of a variable normally a 'test' instruction is used on a page of memory, and instead of setting the variable, the permission on the page are changed triggering a page fault. Which GCs do that? The only one I know is Azul's Pauseless JVM GC, but that's a kind of a special case, given that it needs support from the kernel.

All of HotSpot's GCs for example. Here's a survey of different approaches for stopping in GC.

http://dl.acm.org/authorize.cfm?key=N98613

Also note that Azul almost certainly has the same mechanism to do things like stop the world for dynamic class loading, even if it isn't using it for GC when running the pauseless collector.

And Section 4 and 5 of this paper talks a bit more about it's implemented http://chrisseaton.com/rubytruffle/icooolps15-safepoints/saf....

Re: Are Go maps sensitive to data races?

#73
post #69

Golang devs should have a look at Clojure and it's `core.async` library. It works very similarly to Go (heavily inspired by the good stuff), but all data structures are persistent, meaning you will never have problems with concurrent mutations (because there there are no mutations in the API, only internally). I recommend Go users to install the boot utility, and playing around with Clojure & core.async. These commun…

It's been a while since I used Clojure, so I apologize if what I'm saying is wrong or out of date. Having used both Clojure and Go there are some significant differences in how coroutines work in each. For instance, in Go making a blocking system call inside of a goroutine "just works" as Go will create additional goroutines as necessary. But if you do the equivalent in Clojure, you risk thread starvation. "However i…

I did not know this, thank you very much! Enlightening indeed.

Re: Are Go maps sensitive to data races?

#74
post #71

Earlier quoted context omitted.

> Except instead of a variable normally a 'test' instruction is used on a page of memory, and instead of setting the variable, the permission on the page are changed triggering a page fault. Which GCs do that? The only one I know is Azul's Pauseless JVM GC, but that's a kind of a special case, given that it needs support from the kernel.

All of HotSpot's GCs for example. Here's a survey of different approaches for stopping in GC. http://dl.acm.org/authorize.cfm?key=N98613 Also note that Azul almost certainly has the same mechanism to do things like stop the world for dynamic class loading, even if it isn't using it for GC when running the pauseless collector. And Section 4 and 5 of this paper talks a bit more about it's implemented http://chrisseaton…

Thanks, I'll check these out!

Re: Are Go maps sensitive to data races?

#75

Earlier quoted context omitted.

They're really not though. Java has ConcurrentHashMap and isn't slow. Clojure has its persistent HashMap and it isn't slow. Scala has, TWO (?) concurrent hash maps in its core and neither is slow. You know, two thirds of the way through the second decade of the 21st century, it's okay to spend a few cycles not corrupting your data structures.

There are both memory and performance considerations. For a server/db web application this may not be a problem, but for e.g. some logic in a game engine that runs every frame on a mobile device, then using 16 extra locks per map for example isn't a good idea. Nor is having 5% performance overhead. I can agree with an argument that thread-safe should be default and specialized/fast collections should be optional thou…

People who care about 5% performance overhead will never use Go in the first place.

Re: Are Go maps sensitive to data races?

#76

Earlier quoted context omitted.

There are both memory and performance considerations. For a server/db web application this may not be a problem, but for e.g. some logic in a game engine that runs every frame on a mobile device, then using 16 extra locks per map for example isn't a good idea. Nor is having 5% performance overhead. I can agree with an argument that thread-safe should be default and specialized/fast collections should be optional thou…

People who care about 5% performance overhead will never use Go in the first place.

That's just not true. Regardless of language there is always a portion of the code where you need to be careful with performance. I have spent endless hours tweaking map performance in .NET, for example.

Re: Are Go maps sensitive to data races?

#77

I'm increasingly convinced that Go is the new PHP, designed and used by the kind of people who know just enough to be incredibly dangerous to themselves and everyone else they touch.

We detached this subthread from https://news.ycombinator.com/item?id=10688820 and marked it off-topic.

Re: Are Go maps sensitive to data races?

#78

Earlier quoted context omitted.

Java's (pre-concurrent) HashMaps aren't designed for concurrent access. Do you know what they do? They throw a ConcurrentModificationException. Do you know what they don't do? Silently corrupt themselves.

That check probably comes at a performance cost that the Go standard library designers found unacceptable. You don't even need to be modifying it concurrently to read inconsistent state, it's enough to write on one thread and read on another, while the map is updating internally. So in order to prevent inconsistent reads you would have to check for concurrent access on all reads. The .NET BCL Dictionary is just like…

Well, they believed it was worth adding something (from a commit today):

https://github.com/golang/go/commit/50c5042047be3af36e7bb478...

Re: Are Go maps sensitive to data races?

#79

Any data structure that isn't explicitly designed for concurrent access will not work when used concurrently. Since a concurrent map (aka. Dictionary aka. Hashtable) is a lot more complex and slow than a non concurrent one, it's very very unlikely that Go would ship with its standard map type being a concurrent one. It would be a huge waste. More likely there is a separate concurrent map type. It's exactly the same i…

> Since a concurrent map (aka. Dictionary aka. Hashtable) is a lot more complex and slow than a non concurrent one, it's very very unlikely that Go would ship with its standard map type being a concurrent one. It would be a huge waste. We should develop a system where maps are unsynchronised by default, but when you access them from a second thread they are then converted transparently by the runtime to a thread-safe…

No we shouldn't. I would even go further and would say if it's accessed from a different thread it should better fail immediatly with a hard error that everybody can see.

Multithreading isn't something that should be implicit. Either you design your whole module/library/application around to be used from multiple threads (with all the extra work for synchronization and typically also well defined thread boundaries) or you stay with single threading.

Re: Are Go maps sensitive to data races?

#80

Earlier quoted context omitted.

That check probably comes at a performance cost that the Go standard library designers found unacceptable. You don't even need to be modifying it concurrently to read inconsistent state, it's enough to write on one thread and read on another, while the map is updating internally. So in order to prevent inconsistent reads you would have to check for concurrent access on all reads. The .NET BCL Dictionary is just like…

Well, they believed it was worth adding something (from a commit today): https://github.com/golang/go/commit/50c5042047be3af36e7bb478...

That's interesting. Would have liked seeing something like that in the Java and .NET equivalents.
Post reply on HN