Commit e3870aa6 authored by Austin Clements's avatar Austin Clements

runtime: fix assist utilization computation

When commit 510fd135 enabled assists during the scan phase, it failed
to also update the code in the GC controller that computed the assist
CPU utilization and adjusted the trigger based on it. Fix that code so
it uses the start of the scan phase as the wall-clock time when
assists were enabled rather than the start of the mark phase.

Change-Id: I05013734b4448c3e2c730dc7b0b5ee28c86ed8cf
Reviewed-on: https://go-review.googlesource.com/13048Reviewed-by: default avatarRick Hudson <rlh@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 1fb01a88
...@@ -348,6 +348,10 @@ type gcControllerState struct { ...@@ -348,6 +348,10 @@ type gcControllerState struct {
// that the background mark phase started. // that the background mark phase started.
bgMarkStartTime int64 bgMarkStartTime int64
// assistTime is the absolute start time in nanoseconds that
// mutator assists were enabled.
assistStartTime int64
// heapGoal is the goal memstats.heap_live for when this cycle // heapGoal is the goal memstats.heap_live for when this cycle
// ends. This is computed at the beginning of each cycle. // ends. This is computed at the beginning of each cycle.
heapGoal uint64 heapGoal uint64
...@@ -500,15 +504,19 @@ func (c *gcControllerState) endCycle() { ...@@ -500,15 +504,19 @@ func (c *gcControllerState) endCycle() {
// growth if we had the desired CPU utilization). The // growth if we had the desired CPU utilization). The
// difference between this estimate and the GOGC-based goal // difference between this estimate and the GOGC-based goal
// heap growth is the error. // heap growth is the error.
//
// TODO(austin): next_gc is based on heap_reachable, not
// heap_marked, which means the actual growth ratio
// technically isn't comparable to the trigger ratio.
goalGrowthRatio := float64(gcpercent) / 100 goalGrowthRatio := float64(gcpercent) / 100
actualGrowthRatio := float64(memstats.heap_live)/float64(memstats.heap_marked) - 1 actualGrowthRatio := float64(memstats.heap_live)/float64(memstats.heap_marked) - 1
duration := nanotime() - c.bgMarkStartTime assistDuration := nanotime() - c.assistStartTime
// Assume background mark hit its utilization goal. // Assume background mark hit its utilization goal.
utilization := gcGoalUtilization utilization := gcGoalUtilization
// Add assist utilization; avoid divide by zero. // Add assist utilization; avoid divide by zero.
if duration > 0 { if assistDuration > 0 {
utilization += float64(c.assistTime) / float64(duration*int64(gomaxprocs)) utilization += float64(c.assistTime) / float64(assistDuration*int64(gomaxprocs))
} }
triggerError := goalGrowthRatio - c.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-c.triggerRatio) triggerError := goalGrowthRatio - c.triggerRatio - utilization/gcGoalUtilization*(actualGrowthRatio-c.triggerRatio)
...@@ -979,6 +987,7 @@ func gc(mode int) { ...@@ -979,6 +987,7 @@ func gc(mode int) {
now = nanotime() now = nanotime()
pauseNS += now - pauseStart pauseNS += now - pauseStart
tScan = now tScan = now
gcController.assistStartTime = now
gcscan_m() gcscan_m()
// Enter mark phase. // Enter mark phase.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment