Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: conflicting escape analysis result and benchmark result output messages #46908

Closed
go101 opened this issue Jun 24, 2021 · 4 comments

Comments

@go101
Copy link

go101 commented Jun 24, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.5 linux/amd64

Does this issue reproduce with the latest release?

Yes

What did you do?

package concat

import (
    "testing"
)

var s33 = []byte{32: 'b'}
var a = string(s33)


func Benchmark_e_33(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = a + a // a + a does not escape
    }
}

What did you expect to see?

No allocations. Or says "a + a escapes to heap"

What did you see instead?

$ go test -gcflags=-m
..
./concat_test.go:13:15: a + a does not escape
..
$ go test -bench=. -benchmem 
...
Benchmark_e_33-4   	14399670	        75.39 ns/op	      80 B/op	       1 allocs/op
@martisch
Copy link
Contributor

martisch commented Jun 24, 2021

I dont think the interpretation of heap allocation if and only if escapes is correct. The stack is only used for small and fixed size allocations currently. Therefore some variables/expressions might not escape but are still allocated on the heap. Examples I can think of in the current go gc implementation are big fixed size slice literals, maps past the initial small size, string concatenations larger than 32 bytes. Even with escape analysis not changing the compiler might choose to do heap allocations for different situations and cut offs. Stack allocation is an optimisation and escape analysis is just one factor to decide if stack allocation should be done but the final decision depends on compiler implementation outside escape analysis. The compiler might choose to allocate everything on the heap in a very simplistic version.

@toothrot
Copy link
Contributor

I agree with martisch's assesment. pprof may be a more helpful tool for understanding why this string concatenation is triggering an allocation.

I don't think this is an issue with Go or the tooling, so please see https://golang.org/wiki/Questions for further answers.

@go101
Copy link
Author

go101 commented Jun 25, 2021

@toothrot
pprof is too heavy to the task.

@martisch
I thought it again, and now think the message should be "a + a does not escape" instead. The accurate meaning of it is "the header part of a + a does not escape". As you have explained, it is hard (impossible actually) for the compiler to determine whether or not the underlying part of "a + a" will escape to heap.

@go101
Copy link
Author

go101 commented Jun 25, 2021

Here is another example, for which the escape analysis messages are good in my opinion.
At run time, the underlying part of y does escape, but the underlying part of x doesn't.

package main

var bs32 = make([]byte, 32)
var bs33 = make([]byte, 33)

func main() {
	x := string(bs32) // string(bs32) does not escape
	y := string(bs33) // string(bs32) does not escape
	println(x)
	println(y)
}

@golang golang locked and limited conversation to collaborators Jun 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants