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: run out of memory during -N -l compilation #45897

Closed
badpooh opened this issue May 1, 2021 · 6 comments
Closed

cmd/compile: run out of memory during -N -l compilation #45897

badpooh opened this issue May 1, 2021 · 6 comments
Labels

Comments

@badpooh
Copy link

@badpooh badpooh commented May 1, 2021

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

$ go version
go version go1.16.3 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/user/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/user/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.3"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1710213132=/tmp/go-build -gno-record-gcc-switches"

What did you do?

main.go

package main

import (
	"github.com/yuin/goldmark"
	"github.com/yuin/goldmark/text"
)

func main() {
	parser := goldmark.DefaultParser()
	parser.Parse(text.NewReader([]byte(``)))
}

go.mod

module playground

go 1.16

require github.com/yuin/goldmark v1.3.5 // indirect

build main.go with gcflags all=-N -l

$ go build -gcflags "all=-N -l" main.go

What did you expect to see?

Successfully built.

What did you see instead?

$ go build -gcflags "all=-N -l" main.go
go build github.com/yuin/goldmark/util: /usr/lib/go/pkg/tool/linux_amd64/compile: signal: killed

I notice memory have ran out, and I have 10GB free memory before building.

@davecheney
Copy link
Contributor

@davecheney davecheney commented May 1, 2021

Can you please check dmesg and post the entire output of the OOM killer. Thank you

Loading

@badpooh
Copy link
Author

@badpooh badpooh commented May 1, 2021

Loading

@davecheney
Copy link
Contributor

@davecheney davecheney commented May 1, 2021

5.2gb rss does seem excessive.

Loading

@davecheney davecheney changed the title cmd/compile: run out of memory during compilation cmd/compile: run out of memory during -N -l compilaiton May 1, 2021
@davecheney davecheney changed the title cmd/compile: run out of memory during -N -l compilaiton cmd/compile: run out of memory during -N -l compilation May 1, 2021
@randall77
Copy link
Contributor

@randall77 randall77 commented May 1, 2021

Likely this is compiling github.com/yuin/goldmark@v1.3.5/util/html5entities.go which is a big map with complicated entries.
I can compile using about 3GB on my machine. Not sure why it goes to 5+GB for you, but yes, that seems overkill.
Without -N -l it takes under 200MB. In particular, -N is the culprit.

Probably a dup of #41058 .
Also see #37741 for another instance of this code causing trouble :(

Looks like lots of time+space spent in regalloc. The liveness maps get really big. (~30K blocks, ~5K live values per block.) Maybe there's something we could do here. Turn on some processing that's normally off with -N when functions are big, or something like that. Maybe there's also a tweak to map building that could trim liveness (e.g. a VarKill in the right spot).
Improving regalloc to make it not use quadratic space would be even better, but that's not easy.

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented May 3, 2021

Looks like the O(n^2) behavior comes from putting constant expressions in the entry block and not CSEing or tightening them.
The entry block contains lots of things like:

v650 (?) = LEAQ <*uint8> {type.[1]int} v3
v789 (?) = LEAQ <*uint8> {type.[1]int} v3
v913 (?) = LEAQ <*uint8> {type.[1]int} v3

One for each allocation in the map literal (the code in question allocates a [1]int as part of the map entry). They are all only used for a single map assignment. At the first map entry assignment, they are all live.

Loading

@gopherbot
Copy link

@gopherbot gopherbot commented May 3, 2021

Change https://golang.org/cl/316369 mentions this issue: cmd/compile: when compiling with -N, avoid entry block

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants