src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
changeset 57953 d78c910f9069
parent 57507 f6b30bd6804e
child 58264 4e96939a5746
equal deleted inserted replaced
57952:5021d91ba9bd 57953:d78c910f9069
   143 // without needing to check for overflow in "x OP y", because the
   143 // without needing to check for overflow in "x OP y", because the
   144 // ranges for x and y have been restricted.
   144 // ranges for x and y have been restricted.
   145 STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
   145 STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
   146 const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
   146 const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
   147 const size_t max_green_zone = max_yellow_zone / 2;
   147 const size_t max_green_zone = max_yellow_zone / 2;
   148 const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_buffers.
   148 const size_t max_red_zone = INT_MAX; // For dcqs.set_max_cards.
   149 STATIC_ASSERT(max_yellow_zone <= max_red_zone);
   149 STATIC_ASSERT(max_yellow_zone <= max_red_zone);
   150 
   150 
   151 // Range check assertions for green zone values.
   151 // Range check assertions for green zone values.
   152 #define assert_zone_constraints_g(green)                        \
   152 #define assert_zone_constraints_g(green)                        \
   153   do {                                                          \
   153   do {                                                          \
   230 
   230 
   231 jint G1ConcurrentRefine::initialize() {
   231 jint G1ConcurrentRefine::initialize() {
   232   return _thread_control.initialize(this, max_num_threads());
   232   return _thread_control.initialize(this, max_num_threads());
   233 }
   233 }
   234 
   234 
       
   235 static size_t buffers_to_cards(size_t value) {
       
   236   return value * G1UpdateBufferSize;
       
   237 }
       
   238 
   235 static size_t calc_min_yellow_zone_size() {
   239 static size_t calc_min_yellow_zone_size() {
   236   size_t step = G1ConcRefinementThresholdStep;
   240   size_t step = buffers_to_cards(G1ConcRefinementThresholdStep);
   237   uint n_workers = G1ConcurrentRefine::max_num_threads();
   241   uint n_workers = G1ConcurrentRefine::max_num_threads();
   238   if ((max_yellow_zone / step) < n_workers) {
   242   if ((max_yellow_zone / step) < n_workers) {
   239     return max_yellow_zone;
   243     return max_yellow_zone;
   240   } else {
   244   } else {
   241     return step * n_workers;
   245     return step * n_workers;
   245 static size_t calc_init_green_zone() {
   249 static size_t calc_init_green_zone() {
   246   size_t green = G1ConcRefinementGreenZone;
   250   size_t green = G1ConcRefinementGreenZone;
   247   if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
   251   if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
   248     green = ParallelGCThreads;
   252     green = ParallelGCThreads;
   249   }
   253   }
       
   254   green = buffers_to_cards(green);
   250   return MIN2(green, max_green_zone);
   255   return MIN2(green, max_green_zone);
   251 }
   256 }
   252 
   257 
   253 static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
   258 static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
   254   size_t config = G1ConcRefinementYellowZone;
   259   size_t config = buffers_to_cards(G1ConcRefinementYellowZone);
   255   size_t size = 0;
   260   size_t size = 0;
   256   if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
   261   if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
   257     size = green * 2;
   262     size = green * 2;
   258   } else if (green < config) {
   263   } else if (green < config) {
   259     size = config - green;
   264     size = config - green;
   264 }
   269 }
   265 
   270 
   266 static size_t calc_init_red_zone(size_t green, size_t yellow) {
   271 static size_t calc_init_red_zone(size_t green, size_t yellow) {
   267   size_t size = yellow - green;
   272   size_t size = yellow - green;
   268   if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
   273   if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
   269     size_t config = G1ConcRefinementRedZone;
   274     size_t config = buffers_to_cards(G1ConcRefinementRedZone);
   270     if (yellow < config) {
   275     if (yellow < config) {
   271       size = MAX2(size, config - yellow);
   276       size = MAX2(size, config - yellow);
   272     }
   277     }
   273   }
   278   }
   274   return MIN2(yellow + size, max_red_zone);
   279   return MIN2(yellow + size, max_red_zone);
   320 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
   325 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
   321   _thread_control.print_on(st);
   326   _thread_control.print_on(st);
   322 }
   327 }
   323 
   328 
   324 static size_t calc_new_green_zone(size_t green,
   329 static size_t calc_new_green_zone(size_t green,
   325                                   double log_buffer_scan_time,
   330                                   double logged_cards_scan_time,
   326                                   size_t processed_log_buffers,
   331                                   size_t processed_logged_cards,
   327                                   double goal_ms) {
   332                                   double goal_ms) {
   328   // Adjust green zone based on whether we're meeting the time goal.
   333   // Adjust green zone based on whether we're meeting the time goal.
   329   // Limit to max_green_zone.
   334   // Limit to max_green_zone.
   330   const double inc_k = 1.1, dec_k = 0.9;
   335   const double inc_k = 1.1, dec_k = 0.9;
   331   if (log_buffer_scan_time > goal_ms) {
   336   if (logged_cards_scan_time > goal_ms) {
   332     if (green > 0) {
   337     if (green > 0) {
   333       green = static_cast<size_t>(green * dec_k);
   338       green = static_cast<size_t>(green * dec_k);
   334     }
   339     }
   335   } else if (log_buffer_scan_time < goal_ms &&
   340   } else if (logged_cards_scan_time < goal_ms &&
   336              processed_log_buffers > green) {
   341              processed_logged_cards > green) {
   337     green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
   342     green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
   338     green = MIN2(green, max_green_zone);
   343     green = MIN2(green, max_green_zone);
   339   }
   344   }
   340   return green;
   345   return green;
   341 }
   346 }
   348 
   353 
   349 static size_t calc_new_red_zone(size_t green, size_t yellow) {
   354 static size_t calc_new_red_zone(size_t green, size_t yellow) {
   350   return MIN2(yellow + (yellow - green), max_red_zone);
   355   return MIN2(yellow + (yellow - green), max_red_zone);
   351 }
   356 }
   352 
   357 
   353 void G1ConcurrentRefine::update_zones(double log_buffer_scan_time,
   358 void G1ConcurrentRefine::update_zones(double logged_cards_scan_time,
   354                                       size_t processed_log_buffers,
   359                                       size_t processed_logged_cards,
   355                                       double goal_ms) {
   360                                       double goal_ms) {
   356   log_trace( CTRL_TAGS )("Updating Refinement Zones: "
   361   log_trace( CTRL_TAGS )("Updating Refinement Zones: "
   357                          "log buffer scan time: %.3fms, "
   362                          "logged cards scan time: %.3fms, "
   358                          "processed buffers: " SIZE_FORMAT ", "
   363                          "processed cards: " SIZE_FORMAT ", "
   359                          "goal time: %.3fms",
   364                          "goal time: %.3fms",
   360                          log_buffer_scan_time,
   365                          logged_cards_scan_time,
   361                          processed_log_buffers,
   366                          processed_logged_cards,
   362                          goal_ms);
   367                          goal_ms);
   363 
   368 
   364   _green_zone = calc_new_green_zone(_green_zone,
   369   _green_zone = calc_new_green_zone(_green_zone,
   365                                     log_buffer_scan_time,
   370                                     logged_cards_scan_time,
   366                                     processed_log_buffers,
   371                                     processed_logged_cards,
   367                                     goal_ms);
   372                                     goal_ms);
   368   _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
   373   _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
   369   _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
   374   _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
   370 
   375 
   371   assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
   376   assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
   374             "yellow: " SIZE_FORMAT ", "
   379             "yellow: " SIZE_FORMAT ", "
   375             "red: " SIZE_FORMAT,
   380             "red: " SIZE_FORMAT,
   376             _green_zone, _yellow_zone, _red_zone);
   381             _green_zone, _yellow_zone, _red_zone);
   377 }
   382 }
   378 
   383 
   379 void G1ConcurrentRefine::adjust(double log_buffer_scan_time,
   384 void G1ConcurrentRefine::adjust(double logged_cards_scan_time,
   380                                 size_t processed_log_buffers,
   385                                 size_t processed_logged_cards,
   381                                 double goal_ms) {
   386                                 double goal_ms) {
   382   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   387   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   383 
   388 
   384   if (G1UseAdaptiveConcRefinement) {
   389   if (G1UseAdaptiveConcRefinement) {
   385     update_zones(log_buffer_scan_time, processed_log_buffers, goal_ms);
   390     update_zones(logged_cards_scan_time, processed_logged_cards, goal_ms);
   386 
   391 
   387     // Change the barrier params
   392     // Change the barrier params
   388     if (max_num_threads() == 0) {
   393     if (max_num_threads() == 0) {
   389       // Disable dcqs notification when there are no threads to notify.
   394       // Disable dcqs notification when there are no threads to notify.
   390       dcqs.set_process_completed_buffers_threshold(G1DirtyCardQueueSet::ProcessCompletedBuffersThresholdNever);
   395       dcqs.set_process_cards_threshold(G1DirtyCardQueueSet::ProcessCardsThresholdNever);
   391     } else {
   396     } else {
   392       // Worker 0 is the primary; wakeup is via dcqs notification.
   397       // Worker 0 is the primary; wakeup is via dcqs notification.
   393       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
   398       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
   394       size_t activate = activation_threshold(0);
   399       size_t activate = activation_threshold(0);
   395       dcqs.set_process_completed_buffers_threshold(activate);
   400       dcqs.set_process_cards_threshold(activate);
   396     }
   401     }
   397     dcqs.set_max_completed_buffers(red_zone());
   402     dcqs.set_max_cards(red_zone());
   398   }
   403   }
   399 
   404 
   400   size_t curr_queue_size = dcqs.num_completed_buffers();
   405   size_t curr_queue_size = dcqs.num_cards();
   401   if ((dcqs.max_completed_buffers() > 0) &&
   406   if ((dcqs.max_cards() > 0) &&
   402       (curr_queue_size >= yellow_zone())) {
   407       (curr_queue_size >= yellow_zone())) {
   403     dcqs.set_completed_buffers_padding(curr_queue_size);
   408     dcqs.set_max_cards_padding(curr_queue_size);
   404   } else {
   409   } else {
   405     dcqs.set_completed_buffers_padding(0);
   410     dcqs.set_max_cards_padding(0);
   406   }
   411   }
   407   dcqs.notify_if_necessary();
   412   dcqs.notify_if_necessary();
   408 }
   413 }
   409 
   414 
   410 size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
   415 size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
   428 }
   433 }
   429 
   434 
   430 bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
   435 bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
   431   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   436   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   432 
   437 
   433   size_t curr_buffer_num = dcqs.num_completed_buffers();
   438   size_t curr_cards = dcqs.num_cards();
   434   // If the number of the buffers falls down into the yellow zone,
   439   // If the number of the cards falls down into the yellow zone,
   435   // that means that the transition period after the evacuation pause has ended.
   440   // that means that the transition period after the evacuation pause has ended.
   436   // Since the value written to the DCQS is the same for all threads, there is no
   441   // Since the value written to the DCQS is the same for all threads, there is no
   437   // need to synchronize.
   442   // need to synchronize.
   438   if (dcqs.completed_buffers_padding() > 0 && curr_buffer_num <= yellow_zone()) {
   443   if (dcqs.max_cards_padding() > 0 && curr_cards <= yellow_zone()) {
   439     dcqs.set_completed_buffers_padding(0);
   444     dcqs.set_max_cards_padding(0);
   440   }
   445   }
   441 
   446 
   442   maybe_activate_more_threads(worker_id, curr_buffer_num);
   447   maybe_activate_more_threads(worker_id, curr_cards);
   443 
   448 
   444   // Process the next buffer, if there are enough left.
   449   // Process the next buffer, if there are enough left.
   445   return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
   450   return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
   446                                                    deactivation_threshold(worker_id));
   451                                                    deactivation_threshold(worker_id));
   447 }
   452 }