Skip to content

Commit

Permalink
event changes for DATAS (#103405)
Browse files Browse the repository at this point in the history
added info for diag to events for DATAS
  • Loading branch information
Maoni0 authored Jun 19, 2024
1 parent c529580 commit 20fc99b
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 60 deletions.
119 changes: 83 additions & 36 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22085,7 +22085,9 @@ void gc_heap::update_end_gc_time_per_heap()
dynamic_heap_count_data_t::sample& sample = dynamic_heap_count_data.samples[dynamic_heap_count_data.sample_index];
sample.elapsed_between_gcs = end_gc_time - last_suspended_end_time;
sample.gc_pause_time = dd_gc_elapsed_time (dynamic_data_of (0));
sample.msl_wait_time = get_msl_wait_time ();
size_t soh_msl_wait_time, uoh_msl_wait_time;
get_msl_wait_time (&soh_msl_wait_time, &uoh_msl_wait_time);
sample.msl_wait_time = soh_msl_wait_time + uoh_msl_wait_time;
sample.gc_index = gc_index;
// could cache this - we will get it again soon in do_post_gc
sample.gc_survived_size = get_total_promoted ();
Expand Down Expand Up @@ -22113,11 +22115,12 @@ void gc_heap::update_end_gc_time_per_heap()
(sample.gc_pause_time ? (sample.gc_survived_size / 1000.0 / sample.gc_pause_time) : 0),
(sample.gc_pause_time ? ((float)sample.gc_survived_size / sample.gc_pause_time / n_heaps) : 0)));

GCEventFireHeapCountSample_V1 (
GCEventFireSizeAdaptationSample_V1 (
(uint64_t)gc_index,
sample.elapsed_between_gcs,
sample.gc_pause_time,
sample.msl_wait_time);
(uint32_t)sample.elapsed_between_gcs,
(uint32_t)sample.gc_pause_time,
(uint32_t)soh_msl_wait_time, (uint32_t)uoh_msl_wait_time,
(uint64_t)total_soh_stable_size, (uint32_t)sample.gen0_budget_per_heap);

dynamic_heap_count_data.sample_index = (dynamic_heap_count_data.sample_index + 1) % dynamic_heap_count_data_t::sample_size;
(dynamic_heap_count_data.current_samples_count)++;
Expand Down Expand Up @@ -25387,10 +25390,10 @@ void gc_heap::calculate_new_heap_count ()
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));

size_t current_gc_index = VolatileLoadWithoutBarrier (&settings.gc_index);
float median_gen2_tcp_percent = 0.0f;
float median_gen2_tcp = 0.0f;
if (dynamic_heap_count_data.current_gen2_samples_count >= (dynamic_heap_count_data.processed_gen2_samples_count + dynamic_heap_count_data_t::sample_size))
{
median_gen2_tcp_percent = dynamic_heap_count_data.get_median_gen2_gc_percent ();
median_gen2_tcp = dynamic_heap_count_data.get_median_gen2_gc_percent ();
}

// If there was a blocking gen2 GC, the overhead would be very large and most likely we would not pick it. So we
Expand Down Expand Up @@ -25449,7 +25452,7 @@ void gc_heap::calculate_new_heap_count ()
}

dprintf (6666, ("median tcp: %.3f, avg tcp: %.3f, gen2 tcp %.3f(%.3f, %.3f, %.3f)",
median_throughput_cost_percent, avg_throughput_cost_percent, median_gen2_tcp_percent,
median_throughput_cost_percent, avg_throughput_cost_percent, median_gen2_tcp,
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));

int extra_heaps = (n_max_heaps >= 16) + (n_max_heaps >= 64);
Expand All @@ -25476,13 +25479,30 @@ void gc_heap::calculate_new_heap_count ()
{
dynamic_heap_count_data.add_to_recorded_tcp (median_throughput_cost_percent);

float tcp_to_consider = 0.0;
if (dynamic_heap_count_data.should_change (median_throughput_cost_percent, &tcp_to_consider, current_gc_index))
{
size_t total_soh_stable_size = get_total_soh_stable_size();
float tcp_to_consider = 0.0f;
int agg_factor = 0;
size_t total_soh_stable_size = 0;
int max_heap_count_datas = 0;
int min_heap_count_datas = 0;
dynamic_heap_count_data_t::adjust_metric adj_metric = dynamic_heap_count_data_t::adjust_metric::not_adjusted;

// For diagnostic purpose. need to init these
dynamic_heap_count_data_t::decide_change_condition change_decision = (dynamic_heap_count_data_t::decide_change_condition)0;
int recorded_tcp_count = 0;
float recorded_tcp_slope = 0.0f;
size_t num_gcs_since_last_change = 0;
float current_around_target_accumulation = 0.0f;
dynamic_heap_count_data_t::decide_adjustment_reason adj_reason = (dynamic_heap_count_data_t::decide_adjustment_reason)0;
int hc_change_freq_factor = 0;
dynamic_heap_count_data_t::hc_change_freq_reason hc_freq_reason = (dynamic_heap_count_data_t::hc_change_freq_reason)0;

if (dynamic_heap_count_data.should_change (median_throughput_cost_percent, &tcp_to_consider, current_gc_index,
&change_decision, &recorded_tcp_count, &recorded_tcp_slope, &num_gcs_since_last_change, &current_around_target_accumulation))
{
total_soh_stable_size = get_total_soh_stable_size();
size_t total_bcd = dynamic_heap_count_data.compute_total_gen0_budget (total_soh_stable_size);
int max_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.min_gen0_new_allocation);
int min_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.max_gen0_new_allocation);
max_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.min_gen0_new_allocation);
min_heap_count_datas = (int)(total_bcd / dynamic_heap_count_data.max_gen0_new_allocation);
int max_heap_count_growth_step = dynamic_heap_count_data.get_max_growth (n_heaps);
int max_heap_count_growth_datas = max_heap_count_datas - n_heaps;
if (max_heap_count_growth_datas < 0)
Expand All @@ -25508,7 +25528,7 @@ void gc_heap::calculate_new_heap_count ()

if (change_int > 0)
{
int agg_factor = dynamic_heap_count_data.get_aggressiveness (change_int);
agg_factor = dynamic_heap_count_data.get_aggressiveness (change_int);
if (agg_factor > 1)
{
change_int *= agg_factor;
Expand All @@ -25518,8 +25538,9 @@ void gc_heap::calculate_new_heap_count ()

if (change_int)
{
dynamic_heap_count_data_t::adjust_metric adj_metric = dynamic_heap_count_data.should_change_hc (max_heap_count_datas, min_heap_count_datas,
max_heap_count_growth, change_int, current_gc_index);
adj_metric = dynamic_heap_count_data.should_change_hc (max_heap_count_datas, min_heap_count_datas,
max_heap_count_growth, change_int, current_gc_index,
&adj_reason, &hc_change_freq_factor, &hc_freq_reason);

// 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.
if (adj_metric != dynamic_heap_count_data_t::adjust_metric::adjust_hc)
Expand All @@ -25545,10 +25566,32 @@ void gc_heap::calculate_new_heap_count ()
dprintf (6666, ("total max gen %.3fmb, total bcd %.3fmb, diff %% %.3f-> +%d hc (%%%.3f)",
mb (total_soh_stable_size), mb (total_bcd), diff_pct, change_int, (change_int * 100.0 / n_heaps)));
}
}

GCEventFireSizeAdaptationTuning_V1 (
(uint16_t)new_n_heaps,
(uint16_t)max_heap_count_datas,
(uint16_t)min_heap_count_datas,
(uint64_t)current_gc_index,
(uint64_t)total_soh_stable_size,
(float)median_throughput_cost_percent,
(float)tcp_to_consider,
(float)current_around_target_accumulation,
(uint16_t)recorded_tcp_count,
(float)recorded_tcp_slope,
(uint32_t)num_gcs_since_last_change,
(uint8_t)agg_factor,
(uint16_t)change_decision,
(uint16_t)adj_reason,
(uint16_t)hc_change_freq_factor,
(uint16_t)hc_freq_reason,
(uint8_t)adj_metric);
}

size_t num_gen2s_since_last_change = 0;

if ((new_n_heaps == n_heaps) && !process_eph_samples_p && process_gen2_samples_p)
{
num_gen2s_since_last_change = dynamic_heap_count_data.current_gen2_samples_count - dynamic_heap_count_data.gen2_last_changed_sample_count;
// If we have already been processing eph samples, we don't need to process gen2.
if ((dynamic_heap_count_data.current_samples_count / dynamic_heap_count_data.current_gen2_samples_count) < 10)
{
Expand All @@ -25559,24 +25602,23 @@ void gc_heap::calculate_new_heap_count ()
int step_down = (n_heaps + 1) / 3;

// The gen2 samples only serve as a backstop so this is quite crude.
if (median_gen2_tcp_percent > target_gen2_tcp)
if (median_gen2_tcp > target_gen2_tcp)
{
new_n_heaps += step_up;
new_n_heaps = min (new_n_heaps, actual_n_max_heaps);
dprintf (6666, ("[CHP2-0] gen2 tcp: %.3f, inc by %d + %d = %d", median_gen2_tcp_percent, step_up, n_heaps, new_n_heaps));
dprintf (6666, ("[CHP2-0] gen2 tcp: %.3f, inc by %d + %d = %d", median_gen2_tcp, step_up, n_heaps, new_n_heaps));

if ((new_n_heaps < actual_n_max_heaps) && dynamic_heap_count_data.is_close_to_max (new_n_heaps, actual_n_max_heaps))
{
dprintf (6666, ("[CHP2-1] %d is close to max heaps %d, grow to max", new_n_heaps, actual_n_max_heaps));
new_n_heaps = actual_n_max_heaps;
}
}
else if ((median_gen2_tcp_percent < (target_gen2_tcp / 2)) &&
((dynamic_heap_count_data.current_gen2_samples_count - dynamic_heap_count_data.gen2_last_changed_sample_count) > 30))
else if ((median_gen2_tcp < (target_gen2_tcp / 2)) && (num_gen2s_since_last_change > 30))
{
new_n_heaps -= step_down;
dprintf (6666, ("[CHP3-0] last gen2 sample count when changed: %Id, gen2 tcp: %.3f, dec by %d, %d -> %d",
dynamic_heap_count_data.gen2_last_changed_sample_count, median_gen2_tcp_percent, step_down, n_heaps, new_n_heaps));
dynamic_heap_count_data.gen2_last_changed_sample_count, median_gen2_tcp, step_down, n_heaps, new_n_heaps));
}

if (new_n_heaps != n_heaps)
Expand All @@ -25590,13 +25632,6 @@ void gc_heap::calculate_new_heap_count ()
assert (new_n_heaps <= actual_n_max_heaps);
#endif //STRESS_DYNAMIC_HEAP_COUNT

float reserved_field = (float)0.0;
GCEventFireHeapCountTuning_V1 (
(uint16_t)dynamic_heap_count_data.new_n_heaps,
(uint64_t)VolatileLoadWithoutBarrier (&settings.gc_index),
median_throughput_cost_percent,
reserved_field, reserved_field, reserved_field, reserved_field, reserved_field);

if (process_eph_samples_p)
{
dprintf (6666, ("processed eph samples, updating processed %Id -> %Id", dynamic_heap_count_data.processed_samples_count, dynamic_heap_count_data.current_samples_count));
Expand All @@ -25605,6 +25640,19 @@ void gc_heap::calculate_new_heap_count ()

if (process_gen2_samples_p)
{
dynamic_heap_count_data_t::gen2_sample* gen2_samples = dynamic_heap_count_data.gen2_samples;
GCEventFireSizeAdaptationFullGCTuning_V1 (
(uint16_t)dynamic_heap_count_data.new_n_heaps,
(uint64_t)current_gc_index,
(float)median_gen2_tcp,
(uint32_t)num_gen2s_since_last_change,
(uint32_t)(current_gc_index - gen2_samples[0].gc_index),
(float)gen2_samples[0].gc_percent,
(uint32_t)(current_gc_index - gen2_samples[1].gc_index),
(float)gen2_samples[1].gc_percent,
(uint32_t)(current_gc_index - gen2_samples[2].gc_index),
(float)gen2_samples[2].gc_percent);

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));
dynamic_heap_count_data.processed_gen2_samples_count = dynamic_heap_count_data.current_gen2_samples_count;
}
Expand Down Expand Up @@ -26201,24 +26249,23 @@ bool gc_heap::change_heap_count (int new_n_heaps)
return true;
}

size_t gc_heap::get_msl_wait_time()
void gc_heap::get_msl_wait_time (size_t* soh_msl_wait_time, size_t* uoh_msl_wait_time)
{
assert (dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes);

size_t msl_wait_since_pause = 0;
*soh_msl_wait_time = 0;
*uoh_msl_wait_time = 0;

for (int i = 0; i < n_heaps; i++)
{
gc_heap* hp = g_heaps[i];

msl_wait_since_pause += hp->more_space_lock_soh.msl_wait_time;
soh_msl_wait_time += hp->more_space_lock_soh.msl_wait_time;
hp->more_space_lock_soh.msl_wait_time = 0;

msl_wait_since_pause += hp->more_space_lock_uoh.msl_wait_time;
uoh_msl_wait_time += hp->more_space_lock_uoh.msl_wait_time;
hp->more_space_lock_uoh.msl_wait_time = 0;
}

return msl_wait_since_pause;
}
#endif //DYNAMIC_HEAP_COUNT
#endif //USE_REGIONS
Expand Down
15 changes: 15 additions & 0 deletions src/coreclr/gc/gcevent_serializers.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ struct EventSerializationTraits
* The convention here is that integral types are always serialized as
* little-endian.
*/
template<>
struct EventSerializationTraits<uint8_t>
{
static void Serialize(const uint8_t& value, uint8_t** buffer)
{
**((uint8_t**)buffer) = value;
*buffer += sizeof(uint8_t);
}

static size_t SerializedSize(const uint8_t& value)
{
return sizeof(uint8_t);
}
};

template<>
struct EventSerializationTraits<uint16_t>
{
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/gc/gcevents.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ KNOWN_EVENT(PrvDestroyGCHandle, GCEventProvider_Private, GCEventLevel_Informatio
KNOWN_EVENT(PinPlugAtGCTime, GCEventProvider_Private, GCEventLevel_Verbose, GCEventKeyword_GCPrivate)

DYNAMIC_EVENT(CommittedUsage, GCEventLevel_Information, GCEventKeyword_GC, 1)
DYNAMIC_EVENT(HeapCountTuning, GCEventLevel_Information, GCEventKeyword_GC, 1)
DYNAMIC_EVENT(HeapCountSample, GCEventLevel_Information, GCEventKeyword_GC, 1)
DYNAMIC_EVENT(SizeAdaptationTuning, GCEventLevel_Information, GCEventKeyword_GC, 1)
DYNAMIC_EVENT(SizeAdaptationFullGCTuning, GCEventLevel_Information, GCEventKeyword_GC, 1)
DYNAMIC_EVENT(SizeAdaptationSample, GCEventLevel_Information, GCEventKeyword_GC, 1)

#undef KNOWN_EVENT
#undef DYNAMIC_EVENT
Loading

0 comments on commit 20fc99b

Please sign in to comment.