Skip to content

Commit e50913c

Browse files
rhyshgopherbot
authored andcommitted
runtime: avoid futile mark worker acquisition
During the GC mark phase, one of the first behaviors of findRunnable is to check if it should execute a GC mark worker. Mark workers often run for many milliseconds in a row, so programs that invoke the scheduler more frequently will see that condition trigger only a tiny fraction of the time. Obtaining a mark worker from the gcBgMarkWorkerPool involves a CAS on a single memory location that's shared across the process. When GOMAXPROCS is large, the resulting contention can waste a significant amount of CPU time. But a sufficiently large GOMAXPROCS also means there's no need for fractional mark workers, making it easier to check ahead of time if we need to run a worker. Check, without committing to a particular worker, whether we would even want to run one. For #68399 Change-Id: I5d8578c2101ee20a8a4156a029584356095ea118 Reviewed-on: https://go-review.googlesource.com/c/go/+/602477 Reviewed-by: Michael Pratt <[email protected]> Auto-Submit: Rhys Hiltner <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 2caf638 commit e50913c

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/runtime/mgcpacer.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,17 @@ func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
752752
return nil, now
753753
}
754754

755+
if c.dedicatedMarkWorkersNeeded.Load() <= 0 && c.fractionalUtilizationGoal == 0 {
756+
// No current need for dedicated workers, and no need at all for
757+
// fractional workers. Check before trying to acquire a worker; when
758+
// GOMAXPROCS is large, that can be expensive and is often unnecessary.
759+
//
760+
// When a dedicated worker stops running, the gcBgMarkWorker loop notes
761+
// the need for the worker before returning it to the pool. If we don't
762+
// see the need now, we wouldn't have found it in the pool anyway.
763+
return nil, now
764+
}
765+
755766
// Grab a worker before we commit to running below.
756767
node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
757768
if node == nil {

0 commit comments

Comments
 (0)