mirror of
https://github.com/golang/go
synced 2024-11-12 07:30:25 -07:00
runtime: add more chan benchmarks
Add benchmarks for: 1. non-blocking failing receive (polling of "stop" chan) 2. channel-based semaphore (gate pattern) 3. select-based producer/consumer (pass data through a channel, but also wait on "stop" and "timeout" channels) LGTM=r R=golang-codereviews, r CC=bradfitz, golang-codereviews, iant, khr https://golang.org/cl/59040043
This commit is contained in:
parent
9ed5995cfe
commit
3baceaa151
@ -430,6 +430,30 @@ func TestMultiConsumer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkChanNonblocking(b *testing.B) {
|
||||
const CallsPerSched = 1000
|
||||
procs := runtime.GOMAXPROCS(-1)
|
||||
N := int32(b.N / CallsPerSched)
|
||||
c := make(chan bool, procs)
|
||||
myc := make(chan int)
|
||||
for p := 0; p < procs; p++ {
|
||||
go func() {
|
||||
for atomic.AddInt32(&N, -1) >= 0 {
|
||||
for g := 0; g < CallsPerSched; g++ {
|
||||
select {
|
||||
case <-myc:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
c <- true
|
||||
}()
|
||||
}
|
||||
for p := 0; p < procs; p++ {
|
||||
<-c
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSelectUncontended(b *testing.B) {
|
||||
const CallsPerSched = 1000
|
||||
procs := runtime.GOMAXPROCS(-1)
|
||||
@ -670,6 +694,66 @@ func BenchmarkChanProdConsWork100(b *testing.B) {
|
||||
benchmarkChanProdCons(b, 100, 100)
|
||||
}
|
||||
|
||||
func BenchmarkSelectProdCons(b *testing.B) {
|
||||
const CallsPerSched = 1000
|
||||
procs := runtime.GOMAXPROCS(-1)
|
||||
N := int32(b.N / CallsPerSched)
|
||||
c := make(chan bool, 2*procs)
|
||||
myc := make(chan int, 128)
|
||||
myclose := make(chan bool)
|
||||
for p := 0; p < procs; p++ {
|
||||
go func() {
|
||||
// Producer: sends to myc.
|
||||
foo := 0
|
||||
// Intended to not fire during benchmarking.
|
||||
mytimer := time.After(time.Hour)
|
||||
for atomic.AddInt32(&N, -1) >= 0 {
|
||||
for g := 0; g < CallsPerSched; g++ {
|
||||
// Model some local work.
|
||||
for i := 0; i < 100; i++ {
|
||||
foo *= 2
|
||||
foo /= 2
|
||||
}
|
||||
select {
|
||||
case myc <- 1:
|
||||
case <-mytimer:
|
||||
case <-myclose:
|
||||
}
|
||||
}
|
||||
}
|
||||
myc <- 0
|
||||
c <- foo == 42
|
||||
}()
|
||||
go func() {
|
||||
// Consumer: receives from myc.
|
||||
foo := 0
|
||||
// Intended to not fire during benchmarking.
|
||||
mytimer := time.After(time.Hour)
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case v := <-myc:
|
||||
if v == 0 {
|
||||
break loop
|
||||
}
|
||||
case <-mytimer:
|
||||
case <-myclose:
|
||||
}
|
||||
// Model some local work.
|
||||
for i := 0; i < 100; i++ {
|
||||
foo *= 2
|
||||
foo /= 2
|
||||
}
|
||||
}
|
||||
c <- foo == 42
|
||||
}()
|
||||
}
|
||||
for p := 0; p < procs; p++ {
|
||||
<-c
|
||||
<-c
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkChanCreation(b *testing.B) {
|
||||
const CallsPerSched = 1000
|
||||
procs := runtime.GOMAXPROCS(-1)
|
||||
@ -694,9 +778,23 @@ func BenchmarkChanCreation(b *testing.B) {
|
||||
|
||||
func BenchmarkChanSem(b *testing.B) {
|
||||
type Empty struct{}
|
||||
c := make(chan Empty, 1)
|
||||
for i := 0; i < b.N; i++ {
|
||||
c <- Empty{}
|
||||
const CallsPerSched = 1000
|
||||
procs := runtime.GOMAXPROCS(0)
|
||||
N := int32(b.N / CallsPerSched)
|
||||
c := make(chan bool, procs)
|
||||
myc := make(chan Empty, procs)
|
||||
for p := 0; p < procs; p++ {
|
||||
go func() {
|
||||
for atomic.AddInt32(&N, -1) >= 0 {
|
||||
for g := 0; g < CallsPerSched; g++ {
|
||||
myc <- Empty{}
|
||||
<-myc
|
||||
}
|
||||
}
|
||||
c <- true
|
||||
}()
|
||||
}
|
||||
for p := 0; p < procs; p++ {
|
||||
<-c
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user