runtime: eliminate contention during stack allocation

Standard-sized stack frames use plain malloc/free
instead of centralized lock-protected FixAlloc.
Benchmark results on HP Z600 (2 x Xeon E5620, 8 HT cores, 2.40GHz)
are as follows:
benchmark                                        old ns/op    new ns/op    delta
BenchmarkStackGrowth                               1045.00       949.00   -9.19%
BenchmarkStackGrowth-2                             3450.00       800.00  -76.81%
BenchmarkStackGrowth-4                             5076.00       513.00  -89.89%
BenchmarkStackGrowth-8                             7805.00       471.00  -93.97%
BenchmarkStackGrowth-16                           11751.00       321.00  -97.27%

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/4657091
This commit is contained in:
Dmitriy Vyukov 2011-07-12 09:24:32 -07:00 committed by Russ Cox
parent daaf29cf93
commit c9152a8568
6 changed files with 67 additions and 39 deletions

View file

@ -6,6 +6,7 @@ package runtime_test
import (
"runtime"
"sync/atomic"
"testing"
)
@ -44,3 +45,31 @@ func TestStopTheWorldDeadlock(t *testing.T) {
stop <- true
runtime.GOMAXPROCS(maxprocs)
}
func stackGrowthRecursive(i int) {
var pad [128]uint64
if i != 0 && pad[0] == 0 {
stackGrowthRecursive(i - 1)
}
}
func BenchmarkStackGrowth(b *testing.B) {
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() {
for atomic.AddInt32(&N, -1) >= 0 {
runtime.Gosched()
for g := 0; g < CallsPerSched; g++ {
stackGrowthRecursive(10)
}
}
c <- true
}()
}
for p := 0; p < procs; p++ {
<-c
}
}