From 28147b528312055b535c6a69d0d4492bd502e1b0 Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Mon, 5 Jan 2026 12:23:14 -0500 Subject: [PATCH] cmd/go: guarantee a minimum of min(4,GOMAXPROCS) to compile -c To allow this, we also increase the size of the pool to allow the minimum number for each action, with an extra 2*GOMAXPROCS number of tokens to boost -c when there are fewer concurrently running actions. That means the pool will now have the size 6*GOMAXPROCS instead of the previous 4*GOMAXPROCS. The goal is to maintain the boosting behavior added by the pool, while guarding from starving compiles when there are too few tokens left, so that the value of -c is always at least min(4,GOMAXPROCS), which is what it was set to before Go 1.26. Cq-Include-Trybots: luci.golang.try:gotip-linux-arm64_c4as16-perf_vs_parent,gotip-linux-arm64_c4ah72-perf_vs_parent,gotip-linux-amd64_c3h88-perf_vs_parent,gotip-linux-amd64_c2s16-perf_vs_parent Change-Id: I113a38584514a6c025d3d1bc727ff8d86a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/734040 Commit-Queue: Michael Matloob Reviewed-by: Cherry Mui TryBot-Bypass: Michael Matloob Reviewed-by: Michael Matloob --- src/cmd/go/internal/work/gc.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go index fc74715f22..6300a9135b 100644 --- a/src/cmd/go/internal/work/gc.go +++ b/src/cmd/go/internal/work/gc.go @@ -217,11 +217,11 @@ func compilerConcurrency() (int, func()) { concurrentProcesses++ // Set aside tokens so that we don't run out if we were running cfg.BuildP concurrent compiles. // We'll set aside one token for each of the action goroutines that aren't currently running a compile. - setAside := cfg.BuildP - concurrentProcesses + setAside := (cfg.BuildP - concurrentProcesses) * minTokens availableTokens := tokens - setAside - // Grab half the remaining tokens: but with a floor of at least 1 token, and + // Grab half the remaining tokens: but with a floor of at least minTokens token, and // a ceiling of the max backend concurrency. - c := max(min(availableTokens/2, maxCompilerConcurrency), 1) + c := max(min(availableTokens/2, maxCompilerConcurrency), minTokens) tokens -= c // Successfully grabbed the tokens. return c, func() { @@ -239,15 +239,18 @@ var ( totalTokens int // total number of tokens: this is used for checking that we get them all back in the end tokens int // number of available tokens concurrentProcesses int // number of currently running compiles + minTokens int // minimum number of tokens to give out ) // initCompilerConcurrencyPool sets the number of tokens in the pool. It needs // to be run after init, so that it can use the value of cfg.BuildP. func initCompilerConcurrencyPool() { - // Size the pool so that the worst case total number of compiles is not more - // than what it was when we capped the concurrency to 4. - oldConcurrencyCap := min(4, maxCompilerConcurrency) - tokens = oldConcurrencyCap * cfg.BuildP + // Size the pool to allow 2*maxCompilerConcurrency extra tokens to + // be distributed amongst the compile actions in addition to the minimum + // of min(4,GOMAXPROCS) tokens for each of the potentially cfg.BuildP + // concurrently running compile actions. + minTokens = min(4, maxCompilerConcurrency) + tokens = 2*maxCompilerConcurrency + minTokens*cfg.BuildP totalTokens = tokens } -- 2.52.0