RFR: Specialize ShenandoahGenerationType to avoid generational check penalty on fast paths

Kelvin Nilsen kdnilsen at openjdk.org
Thu Apr 13 18:17:57 UTC 2023


On Thu, 13 Apr 2023 13:42:52 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:

> The target for this PR is to resolve the performance TODO at `ShenandoahMark::mark_through_ref`.
> The same can probably be used in native barrier code too, if we decide to specialize those with `GENERATION`.
> 
> With sample HyperAlloc test that is configured to stress the marking code:
> 
> 
> $ java -XX:+UseShenandoahGC -XX:+UnlockDiagnosticVMOptions -XX:ShenandoahGCMode=passive -XX:-ShenandoahDegeneratedGC -Xlog:gc+stats -Xms1g -Xmx1g -XX:+AlwaysPreTouch -XX:ParallelGCThreads=1 -jar HyperAlloc-1.0.jar -d 30 -s 800 -t 1
> 
> 
> We have consistent improvements in mark times for about 2.5%, look at average times below:
> 
> 
> # Baseline
> 
> [31.009s][info][gc,stats] Pause Full GC (G)              =   25.546 s (a =   532201 us) (n =    48) (lvls, us =   203125,   539062,   542969,   544922,   559177)
> [31.009s][info][gc,stats] Pause Full GC (N)              =   25.543 s (a =   532136 us) (n =    48) (lvls, us =   203125,   539062,   542969,   544922,   559061)
> [31.009s][info][gc,stats]   Mark                         =   10.076 s (a =   209922 us) (n =    48) (lvls, us =    74609,   212891,   212891,   212891,   215692)
> 
> [31.065s][info][gc,stats] Pause Full GC (G)              =   25.618 s (a =   533715 us) (n =    48) (lvls, us =   230469,   541016,   542969,   544922,   556460)
> [31.065s][info][gc,stats] Pause Full GC (N)              =   25.615 s (a =   533650 us) (n =    48) (lvls, us =   230469,   539062,   542969,   544922,   556338)
> [31.065s][info][gc,stats]   Mark                         =   10.090 s (a =   210202 us) (n =    48) (lvls, us =    83398,   212891,   212891,   214844,   217067)
> 
> [30.975s][info][gc,stats] Pause Full GC (G)              =   25.613 s (a =   533606 us) (n =    48) (lvls, us =   201172,   539062,   544922,   546875,   558696)
> [30.975s][info][gc,stats] Pause Full GC (N)              =   25.611 s (a =   533566 us) (n =    48) (lvls, us =   201172,   539062,   544922,   546875,   558576)
> [30.975s][info][gc,stats]   Mark                         =   10.152 s (a =   211491 us) (n =    48) (lvls, us =    73633,   214844,   214844,   214844,   218065)
> 
> # Patched
> 
> [30.607s][info][gc,stats] Pause Full GC (G)              =   25.224 s (a =   525492 us) (n =    48) (lvls, us =   216797,   531250,   537109,   539062,   541888)
> [30.607s][info][gc,stats] Pause Full GC (N)              =   25.220 s (a =   525411 us) (n =    48) (lvls, us =   216797,   531250,   537109,   539062,   541788)
> [30.607s][info][gc,stats]   Mark                         =    9.841 s (a =   205013 us) (n =    48) (lvls, us =    77734,   207031,   208984,   208984,   211176)
> 
> [30.647s][info][gc,stats] Pause Full GC (G)              =   25.293 s (a =   526937 us) (n =    48) (lvls, us =   287109,   531250,   535156,   539062,   545759)
> [30.647s][info][gc,stats] Pause Full GC (N)              =   25.290 s (a =   526868 us) (n =    48) (lvls, us =   287109,   531250,   535156,   539062,   545660)
> [30.647s][info][gc,stats]   Mark                         =    9.833 s (a =   204856 us) (n =    48) (lvls, us =   101562,   207031,   207031,   207031,   212495)
> 
> [30.640s][info][gc,stats] Pause Full GC (G)              =   25.193 s (a =   524860 us) (n =    48) (lvls, us =   210938,   531250,   535156,   537109,   540524)
> [30.640s][info][gc,stats] Pause Full GC (N)              =   25.190 s (a =   524792 us) (n =    48) (lvls, us =   210938,   531250,   535156,   537109,   540420)
> [30.640s][info][gc,stats]   Mark                         =    9.830 s (a =   204788 us) (n =    48) (lvls, us =    76367,   207031,   207031,   208984,   210008)

Thanks for doing this.

src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp line 296:

> 294:       // ShenandoahHeapRegion::global_oop_iterate_and_fill_dead.  We could either mark all live memory as dirty, or could
> 295:       // use the GLOBAL update-refs scanning of pointers to determine precisely which cards to flag as dirty.
> 296:       if (GENERATION == YOUNG && heap->is_in_old(p)) {

May merit a comment to remind the reader that lines 296-302 disappear if GENERATION==GLOBAL_NON_GEN

src/hotspot/share/gc/shenandoah/shenandoahRegulatorThread.cpp line 75:

> 73:     if (mode == ShenandoahControlThread::none) {
> 74:       if (should_unload_classes()) {
> 75:         if (_control_thread->request_concurrent_gc(GLOBAL_GEN)) {

I'm not following when this new code triggers request_concurrent_GC(GLOBAL_NON_GEN)...

My question may relate to William's.

-------------

Marked as reviewed by kdnilsen (Committer).

PR Review: https://git.openjdk.org/shenandoah/pull/254#pullrequestreview-1383967719
PR Review Comment: https://git.openjdk.org/shenandoah/pull/254#discussion_r1165873202
PR Review Comment: https://git.openjdk.org/shenandoah/pull/254#discussion_r1165876860


More information about the shenandoah-dev mailing list