go cmd/compile: 使用命名返回和非命名返回时,非对称内联成本,

nhaq1z21  于 4个月前  发布在  Go
关注(0)|答案(3)|浏览(43)

你使用的Go版本是什么( go version )?

$ go version
go version go1.14.2 windows/amd64

这个问题在最新版本中是否重现?

是的

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Dante\AppData\Local\go-build
set GOENV=C:\Users\Dante\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Dante\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\Dante\Documents\Code\go3mf\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\Dante\AppData\Local\Temp\go-build018008438=/tmp/go-build -gno-record-gcc-switches

你做了什么?

代码: https://play.golang.org/p/bM-akhk0QXG
go build -gcflags "-m=2"

你期望看到什么?

NewTriangleInline 等同于 NewTriangleNoInline,唯一的区别在于第一个使用了命名返回,而第二个没有,因此我期望两者具有相同的内联成本。

func NewTriangleInline(v1, v2, v3 uint32) (t Triangle) {
	t.SetIndex(0, v1)
	t.SetIndex(1, v2)
	t.SetIndex(2, v3)
	return
}
func NewTriangleNoInline(v1, v2, v3 uint32) Triangle {
	var t Triangle
	t.SetIndex(0, v1)
	t.SetIndex(1, v2)
	t.SetIndex(2, v3)
	return t
}

你看到了什么?

.\foo.go:11:6: can inline NewTriangleInline as: func(uint32, uint32, uint32) Triangle { t.SetIndex(0, v1); t.SetIndex(1, v2); t.SetIndex(2, v3); return  }
.\foo.go:18:6: cannot inline NewTriangleNoInline: function too complex: cost 84 exceeds budget 80
li9yvcax

li9yvcax1#

@randall77 @josharian

h7wcgrx3

h7wcgrx32#

是的,内联成本估算并不十分精确。显式声明计数,隐式声明(参数+返回值)不计算。
这个问题可以解决。
但我担心更一般的问题。内联成本模型只是一个估计值。在某些情况下,它总是会出错,甚至以愚蠢的方式(例如 x := 5; y += xy += 5 )。
要真正理解内联函数的成本,我们需要实际编译,这可能会更加昂贵(但我们最终会在某个时候编译它,所以也许?)。除此之外,我们确实想知道调用站点的成本,这取决于诸如常量参数之类的事物。
所以我想问的是——我们应该在哪里划定界限?什么构成内联成本“错误”,什么不算?我们真的想修复这个错误吗?只是为了让时间推移,导致许多类似的错误慢慢出现?
我倾向于说“不是错误”。即使我们解决了这个错误,也不能保证下一次发布时我们不会重新调整内联器并破坏你的内联。但我愿意听取其他想法。

x7rlezfr

x7rlezfr3#

我同意你的观点,如果内联模型被设计成给出粗略估计,那么这不是一个bug,而是一个改进请求。
我也同意关闭这个问题,如果创建了一个更通用的问题(如果还没有的话)来跟踪完整的内联器。否则,我倾向于保持它打开,直到这个特定情况得到正确处理。
即使我们修复了这个bug,也不能保证我们在下一次发布时不会重新调整内联器的权重并破坏你的内联。
感谢你指出这个其他问题。我会在NewTriangle上花更多的时间来尝试进一步降低它的成本,即使这个请求已经实现,因为它在我的关键路径上。无论如何,这个问题不是为了修复我的特定代码,而是为了跟踪命名返回问题。

相关问题