diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 699aa45a1c0..06a535bf7fd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1865,19 +1865,20 @@ class ShenandoahParallelHeapRegionTask : public WorkerTask { private: ShenandoahHeap* const _heap; ShenandoahHeapRegionClosure* const _blk; + size_t const _stride; shenandoah_padding(0); volatile size_t _index; shenandoah_padding(1); public: - ShenandoahParallelHeapRegionTask(ShenandoahHeapRegionClosure* blk) : + ShenandoahParallelHeapRegionTask(ShenandoahHeapRegionClosure* blk, size_t stride) : WorkerTask("Shenandoah Parallel Region Operation"), - _heap(ShenandoahHeap::heap()), _blk(blk), _index(0) {} + _heap(ShenandoahHeap::heap()), _blk(blk), _stride(stride), _index(0) {} void work(uint worker_id) { ShenandoahParallelWorkerSession worker_session(worker_id); - size_t stride = ShenandoahParallelRegionStride; + size_t stride = _stride; size_t max = _heap->num_regions(); while (Atomic::load(&_index) < max) { @@ -1896,8 +1897,20 @@ class ShenandoahParallelHeapRegionTask : public WorkerTask { void ShenandoahHeap::parallel_heap_region_iterate(ShenandoahHeapRegionClosure* blk) const { assert(blk->is_thread_safe(), "Only thread-safe closures here"); - if (num_regions() > ShenandoahParallelRegionStride) { - ShenandoahParallelHeapRegionTask task(blk); + const uint active_workers = workers()->active_workers(); + const size_t n_regions = num_regions(); + size_t stride = ShenandoahParallelRegionStride; + if (stride == 0 && active_workers > 1) { + // Automatically derive the stride to balance the work between threads + // evenly. Do not try to split work if below the reasonable threshold. + constexpr size_t threshold = 4096; + stride = n_regions <= threshold ? + threshold : + (n_regions + active_workers - 1) / active_workers; + } + + if (n_regions > stride && active_workers > 1) { + ShenandoahParallelHeapRegionTask task(blk, stride); workers()->run_task(&task); } else { heap_region_iterate(blk); diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 29ab75951a5..92dab374efe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -508,9 +508,10 @@ "checking for cancellation, yielding, etc. Larger values improve "\ "marking performance at expense of responsiveness.") \ \ - product(uintx, ShenandoahParallelRegionStride, 1024, EXPERIMENTAL, \ + product(uintx, ShenandoahParallelRegionStride, 0, EXPERIMENTAL, \ "How many regions to process at once during parallel region " \ - "iteration. Affects heaps with lots of regions.") \ + "iteration. Affects heaps with lots of regions. " \ + "Set to 0 to let Shenandoah to decide the best value.") \ \ product(size_t, ShenandoahSATBBufferSize, 1 * K, EXPERIMENTAL, \ "Number of entries in an SATB log buffer.") \