# HG changeset patch # User sangheki # Date 1430247770 25200 # Node ID 9223db5721fe4de254eaa8e9efc7a70f0281300d # Parent ebd5af27fe02b5f28bc8a9c23071a03f0c016f55 8073204: Determining the desired PLAB size adjusts to the the number of threads at the wrong place Summary: Calculate the desired PLAB value for a single thread and then return desired PLAB size according to the current number of threads when needed Reviewed-by: ysr, jwilhelm, tschatzl diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Tue Apr 28 12:02:50 2015 -0700 @@ -83,7 +83,7 @@ &_retained_old_gc_alloc_region); } -void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) { +void G1DefaultAllocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) { AllocationContext_t context = AllocationContext::current(); evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() + old_gc_alloc_region(context)->count()); @@ -99,8 +99,8 @@ } if (ResizePLAB) { - _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(no_of_gc_workers); - _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(no_of_gc_workers); + _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(); + _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(); } } diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Tue Apr 28 12:02:50 2015 -0700 @@ -53,7 +53,7 @@ virtual void release_mutator_alloc_region() = 0; virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0; - virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) = 0; + virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0; virtual void abandon_gc_alloc_regions() = 0; virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0; @@ -114,7 +114,7 @@ virtual void release_mutator_alloc_region(); virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info); - virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info); + virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info); virtual void abandon_gc_alloc_regions(); virtual bool is_retained_old_region(HeapRegion* hr) { diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 28 12:02:50 2015 -0700 @@ -5438,7 +5438,7 @@ phase_times->record_string_dedup_fixup_time(fixup_time_ms); } - _allocator->release_gc_alloc_regions(n_workers, evacuation_info); + _allocator->release_gc_alloc_regions(evacuation_info); g1_rem_set()->cleanup_after_oops_into_collection_set_do(); // Reset and re-enable the hot card cache. diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Apr 28 12:02:50 2015 -0700 @@ -276,7 +276,7 @@ void init_gc_alloc_regions(EvacuationInfo& evacuation_info); // It releases the GC alloc regions at the end of a GC. - void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info); + void release_gc_alloc_regions(EvacuationInfo& evacuation_info); // It does any cleanup that needs to be done on the GC alloc regions // before a Full GC. diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Tue Apr 28 12:02:50 2015 -0700 @@ -48,7 +48,7 @@ } size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) { - size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(); + size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(G1CollectedHeap::heap()->workers()->active_workers()); // Prevent humongous PLAB sizes for two reasons: // * PLABs are allocated using a similar paths as oops, but should // never be in a humongous region diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Apr 28 12:02:50 2015 -0700 @@ -1032,7 +1032,7 @@ to()->set_concurrent_iteration_safe_limit(to()->top()); if (ResizePLAB) { - plab_stats()->adjust_desired_plab_sz(n_workers); + plab_stats()->adjust_desired_plab_sz(); } if (PrintGC && !PrintGCDetails) { @@ -1070,6 +1070,10 @@ _gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } +size_t ParNewGeneration::desired_plab_sz() { + return _plab_stats.desired_plab_sz(GenCollectedHeap::heap()->workers()->active_workers()); +} + static int sum; void ParNewGeneration::waste_some_time() { for (int i = 0; i < 100; i++) { diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Tue Apr 28 12:02:50 2015 -0700 @@ -411,9 +411,7 @@ return &_plab_stats; } - size_t desired_plab_sz() { - return _plab_stats.desired_plab_sz(); - } + size_t desired_plab_sz(); const ParNewTracer* gc_tracer() const { return &_gc_tracer; diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/shared/plab.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/plab.cpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/shared/plab.cpp Tue Apr 28 12:02:50 2015 -0700 @@ -109,10 +109,17 @@ } } -// Compute desired plab size and latch result for later +// Calculates plab size for current number of gc worker threads. +size_t PLABStats::desired_plab_sz(uint no_of_gc_workers) { + assert(no_of_gc_workers > 0, "Number of GC workers should be larger than zero"); + + return align_object_size(_desired_net_plab_sz / MAX2(no_of_gc_workers, 1U)); +} + +// Compute desired plab size for one gc worker thread and latch result for later // use. This should be called once at the end of parallel // scavenge; it clears the sensor accumulators. -void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) { +void PLABStats::adjust_desired_plab_sz() { assert(ResizePLAB, "Not set"); assert(is_object_aligned(max_size()) && min_size() <= max_size(), @@ -135,7 +142,8 @@ target_refills = 1; } size_t used = _allocated - _wasted - _unused; - size_t recent_plab_sz = used / (target_refills * no_of_gc_workers); + // Assumed to have 1 gc worker thread + size_t recent_plab_sz = used / target_refills; // Take historical weighted average _filter.sample(recent_plab_sz); // Clip from above and below, and align to object boundary @@ -146,7 +154,7 @@ if (PrintPLAB) { gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz); } - _desired_plab_sz = new_plab_sz; + _desired_net_plab_sz = new_plab_sz; reset(); } diff -r ebd5af27fe02 -r 9223db5721fe hotspot/src/share/vm/gc_implementation/shared/plab.hpp --- a/hotspot/src/share/vm/gc_implementation/shared/plab.hpp Mon Apr 27 10:04:26 2015 +0200 +++ b/hotspot/src/share/vm/gc_implementation/shared/plab.hpp Tue Apr 28 12:02:50 2015 -0700 @@ -150,13 +150,13 @@ // PLAB book-keeping. class PLABStats VALUE_OBJ_CLASS_SPEC { - size_t _allocated; // Total allocated - size_t _wasted; // of which wasted (internal fragmentation) - size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) - size_t _unused; // Unused in last buffer - size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized + size_t _allocated; // Total allocated + size_t _wasted; // of which wasted (internal fragmentation) + size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) + size_t _unused; // Unused in last buffer + size_t _desired_net_plab_sz; // Output of filter (below), suitably trimmed and quantized AdaptiveWeightedAverage - _filter; // Integrator with decay + _filter; // Integrator with decay void reset() { _allocated = 0; @@ -165,12 +165,12 @@ _unused = 0; } public: - PLABStats(size_t desired_plab_sz_, unsigned wt) : + PLABStats(size_t desired_net_plab_sz_, unsigned wt) : _allocated(0), _wasted(0), _undo_wasted(0), _unused(0), - _desired_plab_sz(desired_plab_sz_), + _desired_net_plab_sz(desired_net_plab_sz_), _filter(wt) { } @@ -182,13 +182,12 @@ return PLAB::max_size(); } - size_t desired_plab_sz() { - return _desired_plab_sz; - } + // Calculates plab size for current number of gc worker threads. + size_t desired_plab_sz(uint no_of_gc_workers); - // Updates the current desired PLAB size. Computes the new desired PLAB size, + // Updates the current desired PLAB size. Computes the new desired PLAB size with one gc worker thread, // updates _desired_plab_sz and clears sensor accumulators. - void adjust_desired_plab_sz(uint no_of_gc_workers); + void adjust_desired_plab_sz(); void add_allocated(size_t v) { Atomic::add_ptr(v, &_allocated);