RFR: 8137022: Concurrent refinement thread adjustment and (de-)activation suboptimal [v3]
Kim Barrett
kbarrett at openjdk.org
Fri Sep 23 06:39:33 UTC 2022
> 8137022: Concurrent refinement thread adjustment and (de-)activation suboptimal
> 8155996: Improve concurrent refinement green zone control
> 8134303: Introduce -XX:-G1UseConcRefinement
>
> Please review this change to the control of concurrent refinement.
>
> This new controller takes a different approach to the problem, addressing a
> number of issues.
>
> The old controller used a multiple of the target number of cards to determine
> the range over which increasing numbers of refinement threads should be
> activated, and finally activating mutator refinement. This has a variety of
> problems. It doesn't account for the processing rate, the rate of new dirty
> cards, or the time available to perform the processing. This often leads to
> unnecessary spikes in the number of running refinement threads. It also tends
> to drive the pending number to the target quickly and keep it there, removing
> the benefit from having pending dirty cards filter out new cards for nearby
> writes. It can't delay and leave excess cards in the queue because it could
> be a long time before another buffer is enqueued.
>
> The old controller was triggered by mutator threads enqueing card buffers,
> when the number of cards in the queue exceeded a threshold near the target.
> This required a complex activation protocol between the mutators and the
> refinement threads.
>
> With the new controller there is a primary refinement thread that periodically
> estimates how many refinement threads need to be running to reach the target
> in time for the next GC, along with whether to also activate mutator
> refinement. If the primary thread stops running because it isn't currently
> needed, it sleeps for a period and reevaluates on wakeup. This eliminates any
> involvement in the activation of refinement threads by mutator threads.
>
> The estimate of how many refinement threads are needed uses a prediction of
> time until the next GC, the number of buffered cards, the predicted rate of
> new dirty cards, and the predicted refinement rate. The number of running
> threads is adjusted based on these periodically performed estimates.
>
> This new approach allows more dirty cards to be left in the queue until late
> in the mutator phase, typically reducing the rate of new dirty cards, which
> reduces the amount of concurrent refinement work needed.
>
> It also smooths out the number of running refinement threads, eliminating the
> unnecessarily large spikes that are common with the old method. One benefit
> is that the number of refinement threads (lazily) allocated is often much
> lower now. (This plus UseDynamicNumberOfGCThreads mitigates the problem
> described in JDK-8153225.)
>
> This change also provides a new method for calculating for the number of dirty
> cards that should be pending at the start of a GC. While this calculation is
> conceptually distinct from the thread control, the two were significanly
> intertwined in the old controller. Changing this calculation separately and
> first would have changed the behavior of the old controller in ways that might
> have introduced regressions. Changing it after the thread control was changed
> would have made it more difficult to test and measure the thread control in a
> desirable configuration.
>
> The old calculation had various problems that are described in JDK-8155996.
> In particular, it can get more or less stuck at low values, and is slow to
> respond to changes.
>
> The old controller provided a number of product options, none of which were
> very useful for real applications, and none of which are very applicable to
> the new controller. All of these are being obsoleted.
>
> -XX:-G1UseAdaptiveConcRefinement
> -XX:G1ConcRefinementGreenZone=<buffer-count>
> -XX:G1ConcRefinementYellowZone=<buffer-count>
> -XX:G1ConcRefinementRedZone=<buffer-count>
> -XX:G1ConcRefinementThresholdStep=<buffer-count>
>
> The new controller *could* use G1ConcRefinementGreenZone to provide a fixed
> value for the target number of cards, though it is poorly named for that.
>
> A configuration that was useful for some kinds of debugging and testing was to
> disable G1UseAdaptiveConcRefinement and set g1ConcRefinementGreenZone to a
> very large value, effectively disabling concurrent refinement. To support
> this use case with the new controller, the -XX:-G1UseConcRefinement diagnostic
> option has been added (see JDK-8155996).
>
> The other options are meaningless for the new controller.
>
> Because of these option changes, a CSR and a release note need to accompany
> this change.
>
> Testing:
> mach5 tier1-6
> various performance tests.
> local (linux-x64) tier1 with -XX:-G1UseConcRefinement
>
> Performance testing found no regressions, but also little or no improvement
> with default options, which was expected. With default options most of our
> performance tests do very little concurrent refinement. And even for those
> that do, while the old controller had a number of problems, the impact of
> those problems is small and hard to measure for most applications.
>
> When reducing G1RSetUpdatingPauseTimePercent the new controller seems to fare
> better, particularly when also reducing MaxGCPauseMillis. specjbb2015 with
> MaxGCPauseMillis=75 and G1RSetUpdatingPauseTimePercent=3 (and other options
> held constant) showed a statistically significant improvement of about 4.5%
> for critical-jOPS. Using the changed controller, the difference between this
> configuration and the default is fairly small, while the baseline shows
> significant degradation with the more restrictive options.
>
> For all tests and configurations the new controller often creates many fewer
> refinement threads.
Kim Barrett has updated the pull request incrementally with three additional commits since the last revision:
- wanted vs needed nomenclature
- remove several spurious "scan"
- delay => wait_time_ms
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/10256/files
- new: https://git.openjdk.org/jdk/pull/10256/files/ffdf6339..9a735bc0
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=10256&range=02
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=10256&range=01-02
Stats: 28 lines in 4 files changed: 1 ins; 0 del; 27 mod
Patch: https://git.openjdk.org/jdk/pull/10256.diff
Fetch: git fetch https://git.openjdk.org/jdk pull/10256/head:pull/10256
PR: https://git.openjdk.org/jdk/pull/10256
More information about the hotspot-dev
mailing list