8152101: Move G1 concurrent refinement adjustment code out of G1CollectorPolicy

Reviewed-by: jmasa, jwilhelm, kbarrett
This commit is contained in:
Mikael Gerdin 2016-03-11 11:22:56 +01:00
parent ed7472e0dd
commit 1e047e54c0
4 changed files with 55 additions and 51 deletions

View file

@ -27,11 +27,13 @@
#include "gc/g1/concurrentG1RefineThread.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1Predictions.hpp"
#include "runtime/java.hpp"
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictor) :
_threads(NULL),
_sample_thread(NULL),
_predictor_sigma(predictor->sigma()),
_hot_card_cache(g1h)
{
// Ergonomically select initial concurrent refinement parameters
@ -49,10 +51,12 @@ ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
}
set_red_zone(MAX2(G1ConcRefinementRedZone, yellow_zone()));
}
ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h);
G1CollectorPolicy* policy = g1h->g1_policy();
ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h, &policy->predictor());
if (cg1r == NULL) {
*ecode = JNI_ENOMEM;
vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
@ -155,3 +159,43 @@ void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
_sample_thread->print_on(st);
st->cr();
}
void ConcurrentG1Refine::adjust(double update_rs_time,
double update_rs_processed_buffers,
double goal_ms) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
if (G1UseAdaptiveConcRefinement) {
const int k_gy = 3, k_gr = 6;
const double inc_k = 1.1, dec_k = 0.9;
size_t g = green_zone();
if (update_rs_time > goal_ms) {
g = (size_t)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
} else {
if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
g = (size_t)MAX2(g * inc_k, g + 1.0);
}
}
// Change the refinement threads params
set_green_zone(g);
set_yellow_zone(g * k_gy);
set_red_zone(g * k_gr);
reinitialize_threads();
size_t processing_threshold_delta = MAX2<size_t>(green_zone() * _predictor_sigma, 1);
size_t processing_threshold = MIN2(green_zone() + processing_threshold_delta,
yellow_zone());
// Change the barrier params
dcqs.set_process_completed_threshold((int)processing_threshold);
dcqs.set_max_completed_queue((int)red_zone());
}
size_t curr_queue_size = dcqs.completed_buffers_num();
if (curr_queue_size >= yellow_zone()) {
dcqs.set_completed_queue_padding(curr_queue_size);
} else {
dcqs.set_completed_queue_padding(0);
}
dcqs.notify_if_necessary();
}

View file

@ -35,6 +35,7 @@
class ConcurrentG1RefineThread;
class G1CollectedHeap;
class G1HotCardCache;
class G1Predictions;
class G1RegionToSpaceMapper;
class G1RemSet;
class DirtyCardQueue;
@ -67,13 +68,15 @@ class ConcurrentG1Refine: public CHeapObj<mtGC> {
size_t _thread_threshold_step;
double _predictor_sigma;
// We delay the refinement of 'hot' cards using the hot card cache.
G1HotCardCache _hot_card_cache;
// Reset the threshold step value based of the current zone boundaries.
void reset_threshold_step();
ConcurrentG1Refine(G1CollectedHeap* g1h);
ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictions);
public:
~ConcurrentG1Refine();
@ -85,6 +88,8 @@ class ConcurrentG1Refine: public CHeapObj<mtGC> {
void init(G1RegionToSpaceMapper* card_counts_storage);
void stop();
void adjust(double update_rs_time, double update_rs_processed_buffers, double goal_ms);
void reinitialize_threads();
// Iterate over all concurrent refinement threads

View file

@ -878,9 +878,9 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t
} else {
update_rs_time_goal_ms -= scan_hcc_time_ms;
}
adjust_concurrent_refinement(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS),
update_rs_time_goal_ms);
_g1->concurrent_g1_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS),
update_rs_time_goal_ms);
cset_chooser()->verify();
}
@ -942,47 +942,6 @@ void G1CollectorPolicy::print_phases() {
phase_times()->print();
}
void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
double update_rs_processed_buffers,
double goal_ms) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
if (G1UseAdaptiveConcRefinement) {
const int k_gy = 3, k_gr = 6;
const double inc_k = 1.1, dec_k = 0.9;
size_t g = cg1r->green_zone();
if (update_rs_time > goal_ms) {
g = (size_t)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
} else {
if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
g = (size_t)MAX2(g * inc_k, g + 1.0);
}
}
// Change the refinement threads params
cg1r->set_green_zone(g);
cg1r->set_yellow_zone(g * k_gy);
cg1r->set_red_zone(g * k_gr);
cg1r->reinitialize_threads();
size_t processing_threshold_delta = MAX2<size_t>(cg1r->green_zone() * _predictor.sigma(), 1);
size_t processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
cg1r->yellow_zone());
// Change the barrier params
dcqs.set_process_completed_threshold((int)processing_threshold);
dcqs.set_max_completed_queue((int)cg1r->red_zone());
}
size_t curr_queue_size = dcqs.completed_buffers_num();
if (curr_queue_size >= cg1r->yellow_zone()) {
dcqs.set_completed_queue_padding(curr_queue_size);
} else {
dcqs.set_completed_queue_padding(0);
}
dcqs.notify_if_necessary();
}
double G1CollectorPolicy::predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) const {
TruncatedSeq* seq = surv_rate_group->get_seq(age);
guarantee(seq->num() > 0, "There should be some young gen survivor samples available. Tried to access with age %d", age);

View file

@ -91,10 +91,6 @@ class G1CollectorPolicy: public CollectorPolicy {
bool verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group);
#endif // PRODUCT
void adjust_concurrent_refinement(double update_rs_time,
double update_rs_processed_buffers,
double goal_ms);
double _pause_time_target_ms;
size_t _pending_cards;