-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Closed
Labels
Description
by suokkos:
Sharing single rand.Rand object using mutex synchronization kills parallel performance if code is using random numbers heavily. To avoid synchronization over-head one can allocate rand.Rand object per goroutine. But rand.Rand object has pretty large internal state that causes memory to be scaling bottleneck. I looked the generator implementation and noticed that it is very simple to make thread safe without mutex locking. This bug report includes my test cases and actual working implementation change. What does 'go version' print? go version devel +423bfcb6b3ce Tue Jul 01 18:04:46 2014 +0300 linux/amd64 (I originally noticed this scaling issue with gccgo 4.9.0 20140405 (experimental) [trunk revision 209157]) What steps reproduce the problem? 1. Download attached gambling.go (parallel implementation of pig dice game example; http://golang.org/doc/codewalk/functions/) 2. go run gambling.go -p unlimitedshared What happened? panic: runtime error: index out of range goroutine 3 [running]: main.roll gambling.go:51 main.play gambling.go:99 main.$nested1 gambling.go:180 created by main.main gambling.go:326 What should have happened instead? Program could complete without errors with minor changes to rngSource implementation. Please provide any additional information below. Other attachments include an unit test case for the issue and possible fix. Changes feel like breaking ABI so I have no idea. But I don't have yet enough understanding how go works to be sure if that kind ABI change is allowed or not. Changes generate deterministic number sequence in random order as long as there is less than _TAP number of simultaneous calls to rngSource.Int63. The change panics at _LEN number of parallel calls even tough any number above _TAP could be handled easily without panic. Possible alternative would be: for feed < 0 { feed -= _LEN } If someone sees enough value in these changes they can be freely taken and modified to acceptable form. I'm unlikely to try to submit them to review any time soon. ATTETION! Change doesn't use explicit atomic writes for rngSource.vec because I assumed that writes to vec index don't affect neighbour entries. But that might not be true in all cpu architectures.
Attachments:
- gambling.go (8076 bytes)
- 0001-test-case-for-threaded-rand-use.patch (11680 bytes)
- 0002-allow-parallel-calls-to-rngSource-Int63.patch (1923 bytes)
Reactions are currently unavailable