8073204: Determining the desired PLAB size adjusts to the the number of threads at the wrong place
authorsangheki
Tue, 28 Apr 2015 12:02:50 -0700
changeset 30571 9223db5721fe
parent 30565 ebd5af27fe02
child 30572 3d36f972d68b
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
hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp
hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
hotspot/src/share/vm/gc_implementation/shared/plab.cpp
hotspot/src/share/vm/gc_implementation/shared/plab.hpp
--- 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();
   }
 }
 
--- 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) {
--- 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.
--- 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.
--- 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
--- 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++) {
--- 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;
--- 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();
 }
--- 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);