RFR: 8027545: Improve object array chunking test in G1's copy_to_survivor_space

Stefan Johansson sjohanss at openjdk.java.net
Thu Sep 10 21:49:04 UTC 2020


On Thu, 10 Sep 2020 14:05:25 GMT, Kim Barrett <kbarrett at openjdk.org> wrote:

>> src/hotspot/share/gc/g1/g1ParScanThreadState.cpp line 68:
>> 
>>> 66:     _old_gen_is_full(false),
>>> 67:     _partial_objarray_chunk_size(ParGCArrayScanChunk),
>>> 68:     _partial_array_stepper(n_workers),
>> 
>> What do you think about saving the chunk size in the stepper instead? Then we don't need to pass it in to `start()` and
>> `next()`. To avoid needing it for the call to `oop_iterate_range()` we could instead have the `Step` include both the
>> start and end index.
>
> See above discussion about naming and factoring.  The same stepper can support multiple array types if the chunk size
> is external to the stepper.

It can, but I think I would prefer multiple "steppers" for that case. This is of course just a matter of taste and I'm
fine with leaving the chunk size external.

>> src/hotspot/share/gc/g1/g1ParScanThreadState.hpp line 84:
>> 
>>> 82:   bool _old_gen_is_full;
>>> 83:   // Size (in elements) of a partial objArray task chunk.
>>> 84:   int _partial_objarray_chunk_size;
>> 
>> I would prefer to skip the "obj"-part here to have more consistent naming or, as mentioned above, include it in the
>> stepper instead.
>
> Some of the naming and factoring I've done is forward looking.
> 
> I think we should consider splitting the copying part as well as the scanning, and chunking the copy of typeArrays. For
> example, JDK-8031565 suggests copying large typeArrays as part of termination waiting; I think splitting them into
> partial array tasks to use the normal parallelism in the framework is better than some new side channel. The chunk size
> for that should probably be substantially larger (and depend on the element size) than for objArray.  Also, Project
> Valhalla is going to add new kinds of arrays that are neither objArray nor typeArray. We'll want to split them too. The
> same splitting calculations can apply, even though the chunk size may be different (and probably depends on the element
> klass).

Ok, keeping the "obj"-part sounds reasonable.

>> src/hotspot/share/gc/g1/g1ParScanThreadState.hpp line 165:
>> 
>>> 163: private:
>>> 164:   inline void do_partial_array(PartialArrayScanTask task);
>>> 165:   inline void start_partial_objArray(G1HeapRegionAttr dest_dir, oop from, oop to);
>> 
>> Same here, drop "obj" for consistent naming and avoiding the camel-case.
>
> See response above about the name of _partial_objarray_chunk_size.  But I should probably be consistent about objarray
> vs objArray.  Since objArray is what it is over in runtime oop-land I'm going to go with that.

Again, we have different taste. We very seldom go with camel-case in members and especially in the middle it looks
strange. Looking through the GC-code I find mostly `objarray` or `obj_array`

>> src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp line 34:
>> 
>>> 32:   // that maximizes available parallelism.
>>> 33:   return n_workers;
>>> 34: }
>> 
>> In preparation for a more advanced logic for the limit, or why not just use the input at the call-site?
>
> Being noncommittal about whether something more "clever" could or should be done.

👍

>> src/hotspot/share/gc/shared/partialArrayTaskStepper.hpp line 57:
>> 
>>> 55:     int _index;                 // Array index for the step.
>>> 56:     uint _ncreate;              // Number of new tasks to create.
>>> 57:   };
>> 
>> I wouldn't mind having getters for those, but it's not a hard request :)
>
> Step is intended to be a trivial data carrier.  A (HotSpot) Pair or std::pair (if we used stdlib) would do, except I
> like named data items.

I prefer them named as well 👍

>> src/hotspot/share/gc/shared/partialArrayTaskStepper.inline.hpp line 103:
>> 
>>> 101:   uint ncreate = MIN2(_task_fannout, MIN2(remaining_tasks, _task_limit + 1) - pending);
>>> 102:   Step result = { start, ncreate };
>>> 103:   return result;
>> 
>> Similar to my comment above, what do you think about trying to write some test for this to verify we never get to many
>> "tasks".
>
> The asserts in the stepper's next() after the increment of to's length verify that we haven't overrun.  I haven't
> thought of a way to verify the algorithm doesn't generate too few tasks though.  Well, other than getting crashes
> because some array elements didn't get processed.  But maybe you mean unit tests?  I will try to write some; I should
> have done so already.

Should have been a bit more clear. I'm talking about unit tests, so if you plan writing some that's great.

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

PR: https://git.openjdk.java.net/jdk/pull/90



More information about the hotspot-gc-dev mailing list