Commit 7d9e16ab authored by Russ Cox's avatar Russ Cox

runtime: add benchmark of heapBitsSetType

There was an old benchmark that measured this indirectly
via allocation, but I don't understand how to factor out the
allocation cost when interpreting the numbers.

Replace with a benchmark that only calls heapBitsSetType,
that does not allocate. This was not possible when the
benchmark was first written, because heapBitsSetType had
not been factored out of mallocgc.

Change-Id: I30f0f02362efab3465a50769398be859832e6640
Reviewed-on: https://go-review.googlesource.com/9701Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent db6f88a8
...@@ -128,3 +128,32 @@ func Envs() []string { return envs } ...@@ -128,3 +128,32 @@ func Envs() []string { return envs }
func SetEnvs(e []string) { envs = e } func SetEnvs(e []string) { envs = e }
var BigEndian = _BigEndian var BigEndian = _BigEndian
// For benchmarking.
func BenchSetType(n int, x interface{}) {
e := *(*eface)(unsafe.Pointer(&x))
t := e._type
var size uintptr
var p unsafe.Pointer
switch t.kind & kindMask {
case _KindPtr:
t = (*ptrtype)(unsafe.Pointer(t)).elem
size = t.size
p = e.data
case _KindSlice:
slice := *(*struct {
ptr unsafe.Pointer
len, cap uintptr
})(e.data)
t = (*slicetype)(unsafe.Pointer(t)).elem
size = t.size * slice.len
p = slice.ptr
}
allocSize := roundupsize(size)
systemstack(func() {
for i := 0; i < n; i++ {
heapBitsSetType(uintptr(p), allocSize, size, t)
}
})
}
...@@ -6,6 +6,7 @@ package runtime_test ...@@ -6,6 +6,7 @@ package runtime_test
import ( import (
"os" "os"
"reflect"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"testing" "testing"
...@@ -197,45 +198,140 @@ func TestHugeGCInfo(t *testing.T) { ...@@ -197,45 +198,140 @@ func TestHugeGCInfo(t *testing.T) {
} }
} }
func BenchmarkSetTypeNoPtr1(b *testing.B) { func BenchmarkSetTypePtr(b *testing.B) {
type NoPtr1 struct { benchSetType(b, new(*byte))
p uintptr
}
var p *NoPtr1
for i := 0; i < b.N; i++ {
p = &NoPtr1{}
}
_ = p
} }
func BenchmarkSetTypeNoPtr2(b *testing.B) {
type NoPtr2 struct { func BenchmarkSetTypePtr8(b *testing.B) {
p, q uintptr benchSetType(b, new([8]*byte))
}
var p *NoPtr2
for i := 0; i < b.N; i++ {
p = &NoPtr2{}
}
_ = p
} }
func BenchmarkSetTypePtr1(b *testing.B) {
type Ptr1 struct { func BenchmarkSetTypePtr16(b *testing.B) {
p *byte benchSetType(b, new([16]*byte))
}
var p *Ptr1
for i := 0; i < b.N; i++ {
p = &Ptr1{}
}
_ = p
} }
func BenchmarkSetTypePtr2(b *testing.B) {
type Ptr2 struct { func BenchmarkSetTypePtr32(b *testing.B) {
p, q *byte benchSetType(b, new([32]*byte))
} }
var p *Ptr2
for i := 0; i < b.N; i++ { func BenchmarkSetTypePtr64(b *testing.B) {
p = &Ptr2{} benchSetType(b, new([64]*byte))
} }
_ = p
func BenchmarkSetTypePtr126(b *testing.B) {
benchSetType(b, new([126]*byte))
}
func BenchmarkSetTypePtr128(b *testing.B) {
benchSetType(b, new([128]*byte))
}
func BenchmarkSetTypePtrSlice(b *testing.B) {
benchSetType(b, make([]*byte, 1<<10))
}
type Node1 struct {
Value [1]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode1(b *testing.B) {
benchSetType(b, new(Node1))
}
func BenchmarkSetTypeNode1Slice(b *testing.B) {
benchSetType(b, make([]Node1, 32))
}
type Node8 struct {
Value [8]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode8(b *testing.B) {
benchSetType(b, new(Node8))
}
func BenchmarkSetTypeNode8Slice(b *testing.B) {
benchSetType(b, make([]Node8, 32))
}
type Node64 struct {
Value [64]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode64(b *testing.B) {
benchSetType(b, new(Node64))
}
func BenchmarkSetTypeNode64Slice(b *testing.B) {
benchSetType(b, make([]Node64, 32))
}
type Node64Dead struct {
Left, Right *byte
Value [64]uintptr
}
func BenchmarkSetTypeNode64Dead(b *testing.B) {
benchSetType(b, new(Node64Dead))
}
func BenchmarkSetTypeNode64DeadSlice(b *testing.B) {
benchSetType(b, make([]Node64Dead, 32))
}
type Node124 struct {
Value [124]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode124(b *testing.B) {
benchSetType(b, new(Node124))
}
func BenchmarkSetTypeNode124Slice(b *testing.B) {
benchSetType(b, make([]Node124, 32))
}
type Node126 struct {
Value [126]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode126(b *testing.B) {
benchSetType(b, new(Node126))
}
func BenchmarkSetTypeNode126Slice(b *testing.B) {
benchSetType(b, make([]Node126, 32))
}
type Node1024 struct {
Value [1024]uintptr
Left, Right *byte
}
func BenchmarkSetTypeNode1024(b *testing.B) {
benchSetType(b, new(Node1024))
}
func BenchmarkSetTypeNode1024Slice(b *testing.B) {
benchSetType(b, make([]Node1024, 32))
}
func benchSetType(b *testing.B, x interface{}) {
v := reflect.ValueOf(x)
t := v.Type()
switch t.Kind() {
case reflect.Ptr:
b.SetBytes(int64(t.Elem().Size()))
case reflect.Slice:
b.SetBytes(int64(t.Elem().Size()) * int64(v.Len()))
}
b.ResetTimer()
runtime.BenchSetType(b.N, x)
} }
func BenchmarkAllocation(b *testing.B) { func BenchmarkAllocation(b *testing.B) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment