Description
What version of Go are you using (go version
)?
Found on go version 1.12.15 and 1.13.6 but not 1.11.13.
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
ppc64le (run via Qemu user mode emulation in a docker container on an AMD64 machine provided by travis-ci.org).
This issue does not occur on amd64, 386, arm or arm64 architectures.
go env
Output (for host machine)
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/home/travis/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/travis/gopath" GOPROXY="" GORACE="" GOROOT="/home/travis/.gimme/versions/go1.12.15.linux.amd64" GOTMPDIR="" GOTOOLDIR="/home/travis/.gimme/versions/go1.12.15.linux.amd64/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build725852664=/tmp/go-build -gno-record-gcc-switches"
What did you do?
Ran the following test:
func TestTickerPerformance(t *testing.T) {
testTicker(t, time.Microsecond*100)
testTicker(t, time.Microsecond*200)
testTicker(t, time.Microsecond*500)
testTicker(t, time.Millisecond)
testTicker(t, time.Millisecond*10)
testTicker(t, time.Millisecond*100)
testTicker(t, time.Millisecond*1000)
}
func testTicker(t *testing.T, d time.Duration) {
count := 0
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
defer cancel()
ticker := time.NewTicker(d)
defer ticker.Stop()
loop:
for {
select {
case <-ticker.C:
count++
case <-ctx.Done():
break loop
}
}
t.Logf("%v ticker emitted %v ticks/sec", d, float64(count)/4.0)
}
Available here also as a playground link (code slightly modified to run from main() instead of as a test): https://play.golang.org/p/-zk7GR62pse (please note this produces the 'expected' output on playground rather than the broken output obtained from the ppc64le emulator).
What did you expect to see?
The playground output:
100µs ticker emitted 10000 ticks/sec
200µs ticker emitted 5000 ticks/sec
500µs ticker emitted 2000 ticks/sec
1ms ticker emitted 1000 ticks/sec
10ms ticker emitted 100 ticks/sec
100ms ticker emitted 10 ticks/sec
1s ticker emitted 1 ticks/sec
Or performance figures close to it (noting that this test isn't perfect and there are good reasons why the 100µs ticker may be observed as emitting somewhat fewer than 10000 ticks/sec).
What did you see instead?
On go 1.12.x on ppc64le (see this travis CI run, scroll down to "Running test suite under ppc64le", then to "TestTickerPerformance", line ~1077): https://travis-ci.org/godbus/dbus/jobs/637768665)
100µs ticker emitted 1 ticks/sec
200µs ticker emitted 1 ticks/sec
500µs ticker emitted 1 ticks/sec
1ms ticker emitted 1 ticks/sec
10ms ticker emitted 1 ticks/sec
100ms ticker emitted 1 ticks/sec
1s ticker emitted 0.75 ticks/sec
This go 1.13.x run has the same result: https://travis-ci.org/godbus/dbus/jobs/637768666
The go 1.11.x run does not have this issue:
100µs ticker emitted 9702.75 ticks/sec
200µs ticker emitted 4995.25 ticks/sec
500µs ticker emitted 1999 ticks/sec
1ms ticker emitted 1000 ticks/sec
10ms ticker emitted 100 ticks/sec
100ms ticker emitted 10 ticks/sec
1s ticker emitted 0.75 ticks/sec
This suggests to me that this may be a regression in golang and not due to a flawed emulator.
Comments
I wanted to independently verify this issue on an actual PowerPC device (rather only test on an emulator), but this is difficult for me to come across, so I have not done this.