mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: benchmark for bulk write barriers
This adds a benchmark of typedslicecopy and its bulk write barriers. For #22460. Change-Id: I439ca3b130bb22944468095f8f18b464e5bb43ca Reviewed-on: https://go-review.googlesource.com/74051 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
7e343134d3
commit
f96b95bcd1
1 changed files with 88 additions and 45 deletions
|
|
@ -517,6 +517,32 @@ func TestUserForcedGC(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeBarrierBenchmark(b *testing.B, f func()) {
|
||||||
|
runtime.GC()
|
||||||
|
var ms runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&ms)
|
||||||
|
//b.Logf("heap size: %d MB", ms.HeapAlloc>>20)
|
||||||
|
|
||||||
|
// Keep GC running continuously during the benchmark, which in
|
||||||
|
// turn keeps the write barrier on continuously.
|
||||||
|
var stop uint32
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
for atomic.LoadUint32(&stop) == 0 {
|
||||||
|
runtime.GC()
|
||||||
|
}
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
defer func() {
|
||||||
|
atomic.StoreUint32(&stop, 1)
|
||||||
|
<-done
|
||||||
|
}()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
f()
|
||||||
|
b.StopTimer()
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkWriteBarrier(b *testing.B) {
|
func BenchmarkWriteBarrier(b *testing.B) {
|
||||||
if runtime.GOMAXPROCS(-1) < 2 {
|
if runtime.GOMAXPROCS(-1) < 2 {
|
||||||
// We don't want GC to take our time.
|
// We don't want GC to take our time.
|
||||||
|
|
@ -546,23 +572,7 @@ func BenchmarkWriteBarrier(b *testing.B) {
|
||||||
const depth = 22 // 64 MB
|
const depth = 22 // 64 MB
|
||||||
root := mkTree(22)
|
root := mkTree(22)
|
||||||
|
|
||||||
runtime.GC()
|
writeBarrierBenchmark(b, func() {
|
||||||
var ms runtime.MemStats
|
|
||||||
runtime.ReadMemStats(&ms)
|
|
||||||
//b.Logf("heap size: %d MB", ms.HeapAlloc>>20)
|
|
||||||
|
|
||||||
// Keep GC running continuously during the benchmark.
|
|
||||||
var stop uint32
|
|
||||||
done := make(chan bool)
|
|
||||||
go func() {
|
|
||||||
for atomic.LoadUint32(&stop) == 0 {
|
|
||||||
runtime.GC()
|
|
||||||
}
|
|
||||||
close(done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
|
|
||||||
var stack [depth]*node
|
var stack [depth]*node
|
||||||
tos := -1
|
tos := -1
|
||||||
|
|
||||||
|
|
@ -589,10 +599,43 @@ func BenchmarkWriteBarrier(b *testing.B) {
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
b.StopTimer()
|
|
||||||
atomic.StoreUint32(&stop, 1)
|
|
||||||
<-done
|
|
||||||
|
|
||||||
runtime.KeepAlive(wbRoots)
|
runtime.KeepAlive(wbRoots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkBulkWriteBarrier(b *testing.B) {
|
||||||
|
if runtime.GOMAXPROCS(-1) < 2 {
|
||||||
|
// We don't want GC to take our time.
|
||||||
|
b.Skip("need GOMAXPROCS >= 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a large set of objects we can copy around.
|
||||||
|
const heapSize = 64 << 20
|
||||||
|
type obj [16]*byte
|
||||||
|
ptrs := make([]*obj, heapSize/unsafe.Sizeof(obj{}))
|
||||||
|
for i := range ptrs {
|
||||||
|
ptrs[i] = new(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeBarrierBenchmark(b, func() {
|
||||||
|
const blockSize = 1024
|
||||||
|
var pos int
|
||||||
|
for i := 0; i < b.N; i += blockSize {
|
||||||
|
// Rotate block.
|
||||||
|
block := ptrs[pos : pos+blockSize]
|
||||||
|
first := block[0]
|
||||||
|
copy(block, block[1:])
|
||||||
|
block[blockSize-1] = first
|
||||||
|
|
||||||
|
pos += blockSize
|
||||||
|
if pos+blockSize > len(ptrs) {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.Gosched()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
runtime.KeepAlive(ptrs)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue