From 660b22988b2ee68c630806817f6dfdd70cf43518 Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Tue, 28 Jun 2011 11:15:24 -0400 Subject: [PATCH] runtime: add Semacquire/Semrelease benchmarks R=rsc CC=golang-dev https://golang.org/cl/4625065 --- src/pkg/runtime/sema_test.go | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/pkg/runtime/sema_test.go diff --git a/src/pkg/runtime/sema_test.go b/src/pkg/runtime/sema_test.go new file mode 100644 index 0000000000..d95bb1ec58 --- /dev/null +++ b/src/pkg/runtime/sema_test.go @@ -0,0 +1,100 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "runtime" + "sync/atomic" + "testing" +) + +func BenchmarkSemaUncontended(b *testing.B) { + type PaddedSem struct { + sem uint32 + pad [32]uint32 + } + const CallsPerSched = 1000 + procs := runtime.GOMAXPROCS(-1) + N := int32(b.N / CallsPerSched) + c := make(chan bool, procs) + for p := 0; p < procs; p++ { + go func() { + sem := new(PaddedSem) + for atomic.AddInt32(&N, -1) >= 0 { + runtime.Gosched() + for g := 0; g < CallsPerSched; g++ { + runtime.Semrelease(&sem.sem) + runtime.Semacquire(&sem.sem) + } + } + c <- true + }() + } + for p := 0; p < procs; p++ { + <-c + } +} + +func benchmarkSema(b *testing.B, block, work bool) { + const CallsPerSched = 1000 + const LocalWork = 100 + procs := runtime.GOMAXPROCS(-1) + N := int32(b.N / CallsPerSched) + c := make(chan bool, procs) + c2 := make(chan bool, procs/2) + sem := uint32(0) + if block { + for p := 0; p < procs/2; p++ { + go func() { + runtime.Semacquire(&sem) + c2 <- true + }() + } + } + for p := 0; p < procs; p++ { + go func() { + foo := 0 + for atomic.AddInt32(&N, -1) >= 0 { + runtime.Gosched() + for g := 0; g < CallsPerSched; g++ { + runtime.Semrelease(&sem) + if work { + for i := 0; i < LocalWork; i++ { + foo *= 2 + foo /= 2 + } + } + runtime.Semacquire(&sem) + } + } + c <- foo == 42 + runtime.Semrelease(&sem) + }() + } + if block { + for p := 0; p < procs/2; p++ { + <-c2 + } + } + for p := 0; p < procs; p++ { + <-c + } +} + +func BenchmarkSemaSyntNonblock(b *testing.B) { + benchmarkSema(b, false, false) +} + +func BenchmarkSemaSyntBlock(b *testing.B) { + benchmarkSema(b, true, false) +} + +func BenchmarkSemaWorkNonblock(b *testing.B) { + benchmarkSema(b, false, true) +} + +func BenchmarkSemaWorkBlock(b *testing.B) { + benchmarkSema(b, true, true) +}