Skip to content

testing: don't truncate allocs/op #24631

@teh-cmc

Description

@teh-cmc
$ go version
go version go1.10.1 linux/amd64

testing.Benchmark gives me flaky allocation reports in the following case:

package main

import (
	"fmt"
	"testing"
)

func main() {
	var Eface interface{}
	res := testing.Benchmark(func(b *testing.B) {
		// i := 1, just in case, to avoid convT2E32's optimization wrt zero-values.
		for i := 1; i < b.N; i++ {
			Eface = uint32(i)
		}
	})
	fmt.Println(res.MemString())
}

The generated code for Eface = uint32(i) is what you'd expect:

;; Eface = uint32(i)
0x0050 00080 (main.go:12)	MOVL	CX, ""..autotmp_3+36(SP)
0x0054 00084 (main.go:12)	LEAQ	type.uint32(SB), AX
0x005b 00091 (main.go:12)	MOVQ	AX, (SP)
0x005f 00095 (main.go:12)	LEAQ	""..autotmp_3+36(SP), DX
0x0064 00100 (main.go:12)	MOVQ	DX, 8(SP)
0x0069 00105 (main.go:12)	PCDATA	$0, $1
0x0069 00105 (main.go:12)	CALL	runtime.convT2E32(SB)
0x006e 00110 (main.go:12)	MOVQ	24(SP), AX
0x0073 00115 (main.go:12)	MOVQ	16(SP), CX
0x0078 00120 (main.go:12)	MOVQ	"".&Eface+48(SP), DX
0x007d 00125 (main.go:12)	MOVQ	CX, (DX)
0x0080 00128 (main.go:12)	MOVL	runtime.writeBarrier(SB), CX
0x0086 00134 (main.go:12)	LEAQ	8(DX), DI
0x008a 00138 (main.go:12)	TESTL	CX, CX
0x008c 00140 (main.go:12)	JNE	148
0x008e 00142 (main.go:12)	MOVQ	AX, 8(DX)
0x0092 00146 (main.go:12)	JMP	46
0x0094 00148 (main.go:12)	CALL	runtime.gcWriteBarrier(SB)
0x0099 00153 (main.go:12)	JMP	46

Results:

$ go run main.go
       4 B/op	       1 allocs/op
$ go run main.go
       4 B/op	       1 allocs/op
$ go run main.go
       4 B/op	       1 allocs/op
$ go run main.go
       4 B/op	       0 allocs/op
$ go run main.go
       4 B/op	       0 allocs/op
$ go run main.go
       4 B/op	       1 allocs/op

I.e. while the number of allocated bytes per op is always correct, the number of allocations per op is sometimes wrong (expecting 1 allocs/op).

I guess I'm hitting some kind of rounding error here, but then again why would this behavior not be deterministic? Maybe due to the heuristics around the value of b.N?
I'm not sure what I'm missing here?

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions