diff options
author | Michael Anthony Knyszek <mknyszek@google.com> | 2021-10-04 21:44:06 +0000 |
---|---|---|
committer | Michael Knyszek <mknyszek@google.com> | 2021-11-05 17:46:59 +0000 |
commit | e48e4b4cbbe270bc43e4209dce10c9225254aa64 (patch) | |
tree | f55f95f1d3d3fcd9c268b1a0e27dbc9a261be38a /src/runtime/mgcpacer.go | |
parent | f063e0da28d441065d36f7d676f86d478f67db1f (diff) | |
download | go-e48e4b4cbbe270bc43e4209dce10c9225254aa64.tar.gz go-e48e4b4cbbe270bc43e4209dce10c9225254aa64.zip |
runtime: use a controller to control the scavenge rate
Currently the scavenge rate is determined by a bunch of ad-hoc
mechanisms. Just use a controller instead, now that we have one.
To facilitate this, the scavenger now attempts to scavenge for at least
1 ms at a time, because any less and the timer system is too imprecise to
give useful feedback to the controller. Also increase the amount that we
scavenge at once, to try to reduce the overheads involved (at the
expense of a little bit of latency).
This change also modifies the controller to accept an update period,
because it's useful to allow that to be variable.
Change-Id: I8a15b2355d0a7c6cbac68c957082d5819618f7d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/353975
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/mgcpacer.go')
-rw-r--r-- | src/runtime/mgcpacer.go | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go index 230e78b000..5b699cb298 100644 --- a/src/runtime/mgcpacer.go +++ b/src/runtime/mgcpacer.go @@ -349,9 +349,6 @@ func (c *gcControllerState) init(gcPercent int32) { kp: 0.9, ti: 4.0, - // An update is done once per GC cycle. - period: 1, - // Set a high reset time in GC cycles. // This is inversely proportional to the rate at which we // accumulate error from clipping. By making this very high @@ -677,8 +674,9 @@ func (c *gcControllerState) endCycle(now int64, procs int, userForced bool) floa (float64(scanWork) * (1 - utilization)) // Update cons/mark controller. + // Period for this is 1 GC cycle. oldConsMark := c.consMark - c.consMark = c.consMarkController.next(c.consMark, currentConsMark) + c.consMark = c.consMarkController.next(c.consMark, currentConsMark, 1.0) if debug.gcpacertrace > 0 { printlock() @@ -1259,10 +1257,7 @@ func readGOGC() int32 { type piController struct { kp float64 // Proportional constant. ti float64 // Integral time constant. - tt float64 // Reset time in GC cyles. - - // Period in GC cycles between updates. - period float64 + tt float64 // Reset time. min, max float64 // Output boundaries. @@ -1271,7 +1266,7 @@ type piController struct { errIntegral float64 // Integral of the error from t=0 to now. } -func (c *piController) next(input, setpoint float64) float64 { +func (c *piController) next(input, setpoint, period float64) float64 { // Compute the raw output value. prop := c.kp * (setpoint - input) rawOutput := prop + c.errIntegral @@ -1286,7 +1281,7 @@ func (c *piController) next(input, setpoint float64) float64 { // Update the controller's state. if c.ti != 0 && c.tt != 0 { - c.errIntegral += (c.kp*c.period/c.ti)*(setpoint-input) + (c.period/c.tt)*(output-rawOutput) + c.errIntegral += (c.kp*period/c.ti)*(setpoint-input) + (period/c.tt)*(output-rawOutput) } return output } |