Skip to content

testing: ease writing parallel benchmarks #7090

Description

@bradfitz
Writing contention benchmarks involves some boilerplate:

https://golang.org/cl/46010043/diff/60001/src/pkg/sync/pool_test.go
https://golang.org/cl/49910043/

etc

The general form is:

        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() {
                    var buf bytes.Buffer
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                    f(&buf)
                                }
                    }
                        c <- true
            }()
        }
        for p := 0; p < procs; p++ {
                <-c
    }


But sometimes:

    n0 := uintptr(b.N)
    atomic.AddUintptr(&n, ^uintptr(0)) < n0 {

The testing package seems to cap b.N at 2*1e9, but that's not publicly documented as a
guarantee.

Can/should we say that b.N will always fit in an int32, even if it's of type int?

I once even defensively wrote,

func BenchmarkPool(b *testing.B) {
        procs := runtime.GOMAXPROCS(-1)
    var dec func() bool
    if unsafe.Sizeof(b.N) == 8 {
        n := int64(b.N)
        dec = func() bool {
            return atomic.AddInt64(&n, -1) >= 0
        }
    } else {
                n := int32(b.N)
        dec = func() bool {
            return atomic.AddInt32(&n, -1) >= 0
        }
    }
        var p Pool
    var wg WaitGroup
    for i := 0; i < procs; i++ {
        wg.Add(1)
        go func() {
                        defer wg.Done()
            for dec() {
                                p.Put(1)
                p.Get()
            }
        }()
    }
        wg.Wait()
}

... but felt gross about it.

We should either document this, or provide a means in the testing package to ease
writing benchmarks for contention.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions