In Go 1.19 I tried to switch to using a more correct trigger point in the cons/mark allocation. However, because of how the incorrect trigger point (the precomputed one, gcControllerState.trigger(), as opposed to the actual one, gcControllerState.heapLive at the point the GC is triggered) interacts with the PI controller used to smooth the cons/mark measurements, it turns out to generate a worse result overall.
I think that a smoothing function so sensitive to past history is a bit of a mistake, and this sort of thing could easily happen again. As a result, I propose fixing all of the above in the next release by:
Switching to a simpler smoothing function, like the moving average of cons/mark measurements over the last 2 cycles, then
Using the real trigger point as opposed to the precomputed trigger.
In benchmarks, I've observed that the combination of these two:
Provides a more stable estimate of the actual cons/mark ratio, making the pacer easier to understand,
Is much more accurate at hitting the heap goal, so the GC respects GOGC much more often and reliably, and,
Results in a more stable rate of GC assists in the steady-state overall.
Update: It's worth noting that this is all about transient effects in the pacer. In theory if I let the benchmark from #53738 (comment) run much longer this would all wash away, but the transients do also matter, and I think we should switch to something more simple and stable, if less accurate in the long run (the moving average will never find the true steady-state, but I'm starting to think that's OK).
The text was updated successfully, but these errors were encountered:
It's worth noting that this is all about transient effects in the pacer. In theory if I let the benchmark from #53738 (comment) run much longer this would all wash away, but the transients do also matter, and I think we should switch to something more stable.