@@ -22085,7 +22085,9 @@ void gc_heap::update_end_gc_time_per_heap()
2208522085 dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index];
2208622086 sample.elapsed_between_gcs = end_gc_time - last_suspended_end_time;
2208722087 sample.gc_pause_time = dd_gc_elapsed_time (dynamic_data_of (0));
22088- sample.msl_wait_time = get_msl_wait_time ();
22088+ size_t soh_msl_wait_time, uoh_msl_wait_time;
22089+ get_msl_wait_time (&soh_msl_wait_time, &uoh_msl_wait_time);
22090+ sample.msl_wait_time = soh_msl_wait_time + uoh_msl_wait_time;
2208922091 sample.gc_index = gc_index;
2209022092 // could cache this - we will get it again soon in do_post_gc
2209122093 sample.gc_survived_size = get_total_promoted ();
@@ -22113,11 +22115,12 @@ void gc_heap::update_end_gc_time_per_heap()
2211322115 (sample.gc_pause_time ? (sample.gc_survived_size / 1000.0 / sample.gc_pause_time) : 0),
2211422116 (sample.gc_pause_time ? ((float)sample.gc_survived_size / sample.gc_pause_time / n_heaps) : 0)));
2211522117
22116- GCEventFireHeapCountSample_V1 (
22118+ GCEventFireSizeAdaptationSample_V1 (
2211722119 (uint64_t)gc_index,
22118- sample.elapsed_between_gcs,
22119- sample.gc_pause_time,
22120- sample.msl_wait_time);
22120+ (uint32_t)sample.elapsed_between_gcs,
22121+ (uint32_t)sample.gc_pause_time,
22122+ (uint32_t)soh_msl_wait_time, (uint32_t)uoh_msl_wait_time,
22123+ (uint64_t)total_soh_stable_size, (uint32_t)sample.gen0_budget_per_heap);
2212122124
2212222125 dynamic_heap_count_data.sample_index = (dynamic_heap_count_data.sample_index + 1) % dynamic_heap_count_data_t::sample_size;
2212322126 (dynamic_heap_count_data.current_samples_count)++;
@@ -25387,10 +25390,10 @@ void gc_heap::calculate_new_heap_count ()
2538725390 bool process_gen2_samples_p = (dynamic_heap_count_data.current_gen2_samples_count >= (dynamic_heap_count_data.processed_gen2_samples_count + dynamic_heap_count_data_t::sample_size));
2538825391
2538925392 size_t current_gc_index = VolatileLoadWithoutBarrier (&settings.gc_index);
25390- float median_gen2_tcp_percent = 0.0f;
25393+ float median_gen2_tcp = 0.0f;
2539125394 if (dynamic_heap_count_data.current_gen2_samples_count >= (dynamic_heap_count_data.processed_gen2_samples_count + dynamic_heap_count_data_t::sample_size))
2539225395 {
25393- median_gen2_tcp_percent = dynamic_heap_count_data.get_median_gen2_gc_percent ();
25396+ median_gen2_tcp = dynamic_heap_count_data.get_median_gen2_gc_percent ();
2539425397 }
2539525398
2539625399 // If there was a blocking gen2 GC, the overhead would be very large and most likely we would not pick it. So we
@@ -25449,7 +25452,7 @@ void gc_heap::calculate_new_heap_count ()
2544925452 }
2545025453
2545125454 dprintf (6666, ("median tcp: %.3f, avg tcp: %.3f, gen2 tcp %.3f(%.3f, %.3f, %.3f)",
25452- median_throughput_cost_percent, avg_throughput_cost_percent, median_gen2_tcp_percent ,
25455+ median_throughput_cost_percent, avg_throughput_cost_percent, median_gen2_tcp ,
2545325456 dynamic_heap_count_data.gen2_samples[0].gc_percent, dynamic_heap_count_data.gen2_samples[1].gc_percent, dynamic_heap_count_data.gen2_samples[2].gc_percent));
2545425457
2545525458 int extra_heaps = (n_max_heaps >= 16) + (n_max_heaps >= 64);
@@ -25476,13 +25479,30 @@ void gc_heap::calculate_new_heap_count ()
2547625479 {
2547725480 dynamic_heap_count_data.add_to_recorded_tcp (median_throughput_cost_percent);
2547825481
25479- float tcp_to_consider = 0.0;
25480- if (dynamic_heap_count_data.should_change (median_throughput_cost_percent, &tcp_to_consider, current_gc_index))
25481- {
25482- size_t total_soh_stable_size = get_total_soh_stable_size();
25482+ float tcp_to_consider = 0.0f;
25483+ int agg_factor = 0;
25484+ size_t total_soh_stable_size = 0;
25485+ int max_heap_count_datas = 0;
25486+ int min_heap_count_datas = 0;
25487+ dynamic_heap_count_data_t::adjust_metric adj_metric = dynamic_heap_count_data_t::adjust_metric::not_adjusted;
25488+
25489+ // For diagnostic purpose. need to init these
25490+ dynamic_heap_count_data_t::decide_change_condition change_decision = (dynamic_heap_count_data_t::decide_change_condition)0;
25491+ int recorded_tcp_count = 0;
25492+ float recorded_tcp_slope = 0.0f;
25493+ size_t num_gcs_since_last_change = 0;
25494+ float current_around_target_accumulation = 0.0f;
25495+ dynamic_heap_count_data_t::decide_adjustment_reason adj_reason = (dynamic_heap_count_data_t::decide_adjustment_reason)0;
25496+ int hc_change_freq_factor = 0;
25497+ dynamic_heap_count_data_t::hc_change_freq_reason hc_freq_reason = (dynamic_heap_count_data_t::hc_change_freq_reason)0;
25498+
25499+ if (dynamic_heap_count_data.should_change (median_throughput_cost_percent, &tcp_to_consider, current_gc_index,
25500+ &change_decision, &recorded_tcp_count, &recorded_tcp_slope, &num_gcs_since_last_change, ¤t_around_target_accumulation))
25501+ {
25502+ total_soh_stable_size = get_total_soh_stable_size();
2548325503 size_t total_bcd = dynamic_heap_count_data.compute_total_gen0_budget (total_soh_stable_size);
25484- int max_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.min_gen0_new_allocation);
25485- int min_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.max_gen0_new_allocation);
25504+ max_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.min_gen0_new_allocation);
25505+ min_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.max_gen0_new_allocation);
2548625506 int max_heap_count_growth_step = dynamic_heap_count_data.get_max_growth (n_heaps);
2548725507 int max_heap_count_growth_datas = max_heap_count_datas - n_heaps;
2548825508 if (max_heap_count_growth_datas < 0)
@@ -25508,7 +25528,7 @@ void gc_heap::calculate_new_heap_count ()
2550825528
2550925529 if (change_int > 0)
2551025530 {
25511- int agg_factor = dynamic_heap_count_data.get_aggressiveness (change_int);
25531+ agg_factor = dynamic_heap_count_data.get_aggressiveness (change_int);
2551225532 if (agg_factor > 1)
2551325533 {
2551425534 change_int *= agg_factor;
@@ -25518,8 +25538,9 @@ void gc_heap::calculate_new_heap_count ()
2551825538
2551925539 if (change_int)
2552025540 {
25521- dynamic_heap_count_data_t::adjust_metric adj_metric = dynamic_heap_count_data.should_change_hc (max_heap_count_datas, min_heap_count_datas,
25522- max_heap_count_growth, change_int, current_gc_index);
25541+ adj_metric = dynamic_heap_count_data.should_change_hc (max_heap_count_datas, min_heap_count_datas,
25542+ max_heap_count_growth, change_int, current_gc_index,
25543+ &adj_reason, &hc_change_freq_factor, &hc_freq_reason);
2552325544
2552425545 // If we decide to change budget, we let the next GC calculate the right budget, ie, we delay changing by one GC which is acceptable.
2552525546 if (adj_metric != dynamic_heap_count_data_t::adjust_metric::adjust_hc)
@@ -25545,10 +25566,32 @@ void gc_heap::calculate_new_heap_count ()
2554525566 dprintf (6666, ("total max gen %.3fmb, total bcd %.3fmb, diff %% %.3f-> +%d hc (%%%.3f)",
2554625567 mb (total_soh_stable_size), mb (total_bcd), diff_pct, change_int, (change_int * 100.0 / n_heaps)));
2554725568 }
25548- }
25569+
25570+ GCEventFireSizeAdaptationTuning_V1 (
25571+ (uint16_t)new_n_heaps,
25572+ (uint16_t)max_heap_count_datas,
25573+ (uint16_t)min_heap_count_datas,
25574+ (uint64_t)current_gc_index,
25575+ (uint64_t)total_soh_stable_size,
25576+ (float)median_throughput_cost_percent,
25577+ (float)tcp_to_consider,
25578+ (float)current_around_target_accumulation,
25579+ (uint16_t)recorded_tcp_count,
25580+ (float)recorded_tcp_slope,
25581+ (uint32_t)num_gcs_since_last_change,
25582+ (uint8_t)agg_factor,
25583+ (uint16_t)change_decision,
25584+ (uint16_t)adj_reason,
25585+ (uint16_t)hc_change_freq_factor,
25586+ (uint16_t)hc_freq_reason,
25587+ (uint8_t)adj_metric);
25588+ }
25589+
25590+ size_t num_gen2s_since_last_change = 0;
2554925591
2555025592 if ((new_n_heaps == n_heaps) && !process_eph_samples_p && process_gen2_samples_p)
2555125593 {
25594+ num_gen2s_since_last_change = dynamic_heap_count_data.current_gen2_samples_count - dynamic_heap_count_data.gen2_last_changed_sample_count;
2555225595 // If we have already been processing eph samples, we don't need to process gen2.
2555325596 if ((dynamic_heap_count_data.current_samples_count / dynamic_heap_count_data.current_gen2_samples_count) < 10)
2555425597 {
@@ -25559,24 +25602,23 @@ void gc_heap::calculate_new_heap_count ()
2555925602 int step_down = (n_heaps + 1) / 3;
2556025603
2556125604 // The gen2 samples only serve as a backstop so this is quite crude.
25562- if (median_gen2_tcp_percent > target_gen2_tcp)
25605+ if (median_gen2_tcp > target_gen2_tcp)
2556325606 {
2556425607 new_n_heaps += step_up;
2556525608 new_n_heaps = min (new_n_heaps, actual_n_max_heaps);
25566- dprintf (6666, ("[CHP2-0] gen2 tcp: %.3f, inc by %d + %d = %d", median_gen2_tcp_percent , step_up, n_heaps, new_n_heaps));
25609+ dprintf (6666, ("[CHP2-0] gen2 tcp: %.3f, inc by %d + %d = %d", median_gen2_tcp , step_up, n_heaps, new_n_heaps));
2556725610
2556825611 if ((new_n_heaps < actual_n_max_heaps) && dynamic_heap_count_data.is_close_to_max (new_n_heaps, actual_n_max_heaps))
2556925612 {
2557025613 dprintf (6666, ("[CHP2-1] %d is close to max heaps %d, grow to max", new_n_heaps, actual_n_max_heaps));
2557125614 new_n_heaps = actual_n_max_heaps;
2557225615 }
2557325616 }
25574- else if ((median_gen2_tcp_percent < (target_gen2_tcp / 2)) &&
25575- ((dynamic_heap_count_data.current_gen2_samples_count - dynamic_heap_count_data.gen2_last_changed_sample_count) > 30))
25617+ else if ((median_gen2_tcp < (target_gen2_tcp / 2)) && (num_gen2s_since_last_change > 30))
2557625618 {
2557725619 new_n_heaps -= step_down;
2557825620 dprintf (6666, ("[CHP3-0] last gen2 sample count when changed: %Id, gen2 tcp: %.3f, dec by %d, %d -> %d",
25579- dynamic_heap_count_data.gen2_last_changed_sample_count, median_gen2_tcp_percent , step_down, n_heaps, new_n_heaps));
25621+ dynamic_heap_count_data.gen2_last_changed_sample_count, median_gen2_tcp , step_down, n_heaps, new_n_heaps));
2558025622 }
2558125623
2558225624 if (new_n_heaps != n_heaps)
@@ -25590,13 +25632,6 @@ void gc_heap::calculate_new_heap_count ()
2559025632 assert (new_n_heaps <= actual_n_max_heaps);
2559125633#endif //STRESS_DYNAMIC_HEAP_COUNT
2559225634
25593- float reserved_field = (float)0.0;
25594- GCEventFireHeapCountTuning_V1 (
25595- (uint16_t)dynamic_heap_count_data.new_n_heaps,
25596- (uint64_t)VolatileLoadWithoutBarrier (&settings.gc_index),
25597- median_throughput_cost_percent,
25598- reserved_field, reserved_field, reserved_field, reserved_field, reserved_field);
25599-
2560025635 if (process_eph_samples_p)
2560125636 {
2560225637 dprintf (6666, ("processed eph samples, updating processed %Id -> %Id", dynamic_heap_count_data.processed_samples_count, dynamic_heap_count_data.current_samples_count));
@@ -25605,6 +25640,19 @@ void gc_heap::calculate_new_heap_count ()
2560525640
2560625641 if (process_gen2_samples_p)
2560725642 {
25643+ dynamic_heap_count_data_t::gen2_sample* gen2_samples = dynamic_heap_count_data.gen2_samples;
25644+ GCEventFireSizeAdaptationFullGCTuning_V1 (
25645+ (uint16_t)dynamic_heap_count_data.new_n_heaps,
25646+ (uint64_t)current_gc_index,
25647+ (float)median_gen2_tcp,
25648+ (uint32_t)num_gen2s_since_last_change,
25649+ (uint32_t)(current_gc_index - gen2_samples[0].gc_index),
25650+ (float)gen2_samples[0].gc_percent,
25651+ (uint32_t)(current_gc_index - gen2_samples[1].gc_index),
25652+ (float)gen2_samples[1].gc_percent,
25653+ (uint32_t)(current_gc_index - gen2_samples[2].gc_index),
25654+ (float)gen2_samples[2].gc_percent);
25655+
2560825656 dprintf (6666, ("processed gen2 samples, updating processed %Id -> %Id", dynamic_heap_count_data.processed_gen2_samples_count, dynamic_heap_count_data.current_gen2_samples_count));
2560925657 dynamic_heap_count_data.processed_gen2_samples_count = dynamic_heap_count_data.current_gen2_samples_count;
2561025658 }
@@ -26201,24 +26249,23 @@ bool gc_heap::change_heap_count (int new_n_heaps)
2620126249 return true;
2620226250}
2620326251
26204- size_t gc_heap::get_msl_wait_time( )
26252+ void gc_heap::get_msl_wait_time (size_t* soh_msl_wait_time, size_t* uoh_msl_wait_time )
2620526253{
2620626254 assert (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes);
2620726255
26208- size_t msl_wait_since_pause = 0;
26256+ *soh_msl_wait_time = 0;
26257+ *uoh_msl_wait_time = 0;
2620926258
2621026259 for (int i = 0; i < n_heaps; i++)
2621126260 {
2621226261 gc_heap* hp = g_heaps[i];
2621326262
26214- msl_wait_since_pause += hp->more_space_lock_soh.msl_wait_time;
26263+ soh_msl_wait_time += hp->more_space_lock_soh.msl_wait_time;
2621526264 hp->more_space_lock_soh.msl_wait_time = 0;
2621626265
26217- msl_wait_since_pause += hp->more_space_lock_uoh.msl_wait_time;
26266+ uoh_msl_wait_time += hp->more_space_lock_uoh.msl_wait_time;
2621826267 hp->more_space_lock_uoh.msl_wait_time = 0;
2621926268 }
26220-
26221- return msl_wait_since_pause;
2622226269}
2622326270#endif //DYNAMIC_HEAP_COUNT
2622426271#endif //USE_REGIONS
0 commit comments