go: runtime: select is not fair
What version of Go are you using (go version
)?
$ go version
go version go1.9 linux/amd64
Does this issue reproduce with the latest release?
yes, on 1.9
What operating system and processor architecture are you using (go env
)?
GOARCH=“amd64” GOBIN=“” GOEXE=“” GOHOSTARCH=“amd64” GOHOSTOS=“linux” GOOS=“linux” GOPATH=“/home/bchenebault/DEV/git-oab.si.fr.intraorange/BU900102/ceo-be” GORACE=“” GOROOT=“/usr/local/go” GOTOOLDIR=“/usr/local/go/pkg/tool/linux_amd64” GCCGO=“gccgo” CC=“gcc” GOGCCFLAGS=“-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build913166031=/tmp/go-build -gno-record-gcc-switches” CXX=“g++” CGO_ENABLED=“1” CGO_CFLAGS=“-g -O2” CGO_CPPFLAGS=“” CGO_CXXFLAGS=“-g -O2” CGO_FFLAGS=“-g -O2” CGO_LDFLAGS=“-g -O2” PKG_CONFIG=“pkg-config”
What did you do?
A Go select statement with reflect package function reflect.Select(...)
should block until at least one of the cases can proceed and make a uniform pseudo-random choice. It appears that the behavior has changed since returned values are no longer pseudo-random in specific cases only.
Our case is the following : 2 signaling channels preceding 2 “logic” channels https://play.golang.org/p/0TiMtsRk03
But the same version with only one channel preceding the 2 others works https://play.golang.org/p/sy4RjEEjdg
This case perfectly works on go1.8.3 and below.
What did you expect to see?
A pseudo random distribution
What did you see instead?
A strange distribution, surely not pseudo random
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 33 (29 by maintainers)
Yes, xorshift on ARM is basically 3 instructions thanks to barrel shift, hard to beat. I still think that 1ns in fastrand is not going to have any real world impact, though.
Is 1ns slower important for fastrand? Does it ever use a noticeable amount of cpu in a hot loop? Xorshift is among the fastest with good properties; you can come up with endless number of faster prngs with worse properties, but I fear we might end up in a similar bug some day.
@rasky , xorshift is slower. Otherwise it is good because it gives almost same randomness for high and low bits.
I have other variant for
fastrandn
:It also gives fair distribution
And it is faster than xorshift. But it uses multiplication, and doesn’t fix cases when raw
fastrand
used.https://play.golang.org/p/29n_4OfVQq
What about using xorshift instead?
Outputs:
(https://play.golang.org/p/sD9jmKGWJy)