]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add benchmark of heapBitsSetType
authorRuss Cox <rsc@golang.org>
Sun, 3 May 2015 02:59:35 +0000 (22:59 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 11 May 2015 14:40:27 +0000 (14:40 +0000)
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/9701
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/export_test.go
src/runtime/gc_test.go

index 378a68e01902919484e59bf29340315c2f5d08ab..1efe24c61aad5f9134f205da2bc98e406f2d0ba2 100644 (file)
@@ -128,3 +128,32 @@ func Envs() []string     { return envs }
 func SetEnvs(e []string) { envs = e }
 
 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)
+               }
+       })
+}
index 6abec4cca7b92657e657ca9ecde93d9610c24b75..f049bad49922533402f40107e3a9a7ae3ea44172 100644 (file)
@@ -6,6 +6,7 @@ package runtime_test
 
 import (
        "os"
+       "reflect"
        "runtime"
        "runtime/debug"
        "testing"
@@ -197,45 +198,140 @@ func TestHugeGCInfo(t *testing.T) {
        }
 }
 
-func BenchmarkSetTypeNoPtr1(b *testing.B) {
-       type NoPtr1 struct {
-               p uintptr
-       }
-       var p *NoPtr1
-       for i := 0; i < b.N; i++ {
-               p = &NoPtr1{}
-       }
-       _ = p
+func BenchmarkSetTypePtr(b *testing.B) {
+       benchSetType(b, new(*byte))
 }
-func BenchmarkSetTypeNoPtr2(b *testing.B) {
-       type NoPtr2 struct {
-               p, q uintptr
-       }
-       var p *NoPtr2
-       for i := 0; i < b.N; i++ {
-               p = &NoPtr2{}
-       }
-       _ = p
+
+func BenchmarkSetTypePtr8(b *testing.B) {
+       benchSetType(b, new([8]*byte))
 }
-func BenchmarkSetTypePtr1(b *testing.B) {
-       type Ptr1 struct {
-               p *byte
-       }
-       var p *Ptr1
-       for i := 0; i < b.N; i++ {
-               p = &Ptr1{}
-       }
-       _ = p
+
+func BenchmarkSetTypePtr16(b *testing.B) {
+       benchSetType(b, new([16]*byte))
 }
-func BenchmarkSetTypePtr2(b *testing.B) {
-       type Ptr2 struct {
-               p, q *byte
-       }
-       var p *Ptr2
-       for i := 0; i < b.N; i++ {
-               p = &Ptr2{}
-       }
-       _ = p
+
+func BenchmarkSetTypePtr32(b *testing.B) {
+       benchSetType(b, new([32]*byte))
+}
+
+func BenchmarkSetTypePtr64(b *testing.B) {
+       benchSetType(b, new([64]*byte))
+}
+
+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) {