]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: benchmark for ping-pong in the presence of a CPU hog
authorAustin Clements <austin@google.com>
Wed, 22 Apr 2015 20:38:04 +0000 (16:38 -0400)
committerAustin Clements <austin@google.com>
Fri, 24 Apr 2015 15:12:47 +0000 (15:12 +0000)
This benchmark demonstrates a current problem with the scheduler where
a set of frequently communicating goroutines get very little CPU time
in the presence of another goroutine that hogs that CPU, even if one
of those communicating goroutines is always runnable.

Currently it takes about 0.5 milliseconds to switch between
ping-ponging goroutines in the presence of a CPU hog:

BenchmarkPingPongHog     2000     684287 ns/op

Change-Id: I278848c84f778de32344921ae8a4a8056e4898b0
Reviewed-on: https://go-review.googlesource.com/9288
Reviewed-by: Rick Hudson <rlh@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/proc_test.go

index 88cd48486a53794ec34d097b028946018c585d0e..af90215238f33f0ad2c3068c7be275e8459c797f 100644 (file)
@@ -292,6 +292,43 @@ func main() {
 }
 `
 
+func BenchmarkPingPongHog(b *testing.B) {
+       defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+
+       // Create a CPU hog
+       stop, done := make(chan bool), make(chan bool)
+       go func() {
+               for {
+                       select {
+                       case <-stop:
+                               done <- true
+                               return
+                       default:
+                       }
+               }
+       }()
+
+       // Ping-pong b.N times
+       ping, pong := make(chan bool), make(chan bool)
+       go func() {
+               for j := 0; j < b.N; j++ {
+                       pong <- <-ping
+               }
+               close(stop)
+       }()
+       go func() {
+               for i := 0; i < b.N; i++ {
+                       ping <- <-pong
+               }
+       }()
+       b.ResetTimer()
+       ping <- true // Start ping-pong
+       <-stop
+       b.StopTimer()
+       <-ping // Let last ponger exit
+       <-done // Make sure hog exits
+}
+
 func stackGrowthRecursive(i int) {
        var pad [128]uint64
        if i != 0 && pad[0] == 0 {