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
sminf opened this issue May 1, 2021 · 6 comments
Closed

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

sminf opened this issue May 1, 2021 · 6 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.

Comments

@sminf
Copy link

sminf 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

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

@sminf
Copy link
Author

sminf commented May 1, 2021

dmesg.log

@davecheney
Copy link
Contributor

5.2gb rss does seem excessive.

@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
@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 1, 2021
@randall77
Copy link
Contributor

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.

@randall77
Copy link
Contributor

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.

@gopherbot
Copy link

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

@ALTree ALTree added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 3, 2021
@golang golang locked and limited conversation to collaborators May 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants