Skip to content

Commit b1224b8

Browse files
author
Maoni0
committed
+ introduce a few configs for DATAS fine tuning
+ if the GCGen0MaxBudget config is specified, always honor it including for DATAS
1 parent d1691e1 commit b1224b8

File tree

3 files changed

+99
-39
lines changed

3 files changed

+99
-39
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44216,38 +44216,42 @@ void gc_heap::init_static_data()
4421644216
{
4421744217
size_t gen0_min_size = get_gen0_min_size();
4421844218

44219-
size_t gen0_max_size =
44220-
#ifdef MULTIPLE_HEAPS
44221-
max ((size_t)6*1024*1024, min ( Align(soh_segment_size/2), (size_t)200*1024*1024));
44222-
#else //MULTIPLE_HEAPS
44223-
(
44224-
#ifdef BACKGROUND_GC
44225-
gc_can_use_concurrent ?
44226-
6*1024*1024 :
44227-
#endif //BACKGROUND_GC
44228-
max ((size_t)6*1024*1024, min ( Align(soh_segment_size/2), (size_t)200*1024*1024))
44229-
);
44230-
#endif //MULTIPLE_HEAPS
44231-
44232-
gen0_max_size = max (gen0_min_size, gen0_max_size);
44233-
44234-
if (heap_hard_limit)
44235-
{
44236-
size_t gen0_max_size_seg = soh_segment_size / 4;
44237-
dprintf (GTC_LOG, ("limit gen0 max %zd->%zd", gen0_max_size, gen0_max_size_seg));
44238-
gen0_max_size = min (gen0_max_size, gen0_max_size_seg);
44239-
}
44219+
size_t gen0_max_size = 0;
4424044220

4424144221
size_t gen0_max_size_config = (size_t)GCConfig::GetGCGen0MaxBudget();
4424244222

4424344223
if (gen0_max_size_config)
4424444224
{
44245-
gen0_max_size = min (gen0_max_size, gen0_max_size_config);
44225+
gen0_max_size = gen0_max_size_config;
4424644226

4424744227
#ifdef FEATURE_EVENT_TRACE
4424844228
gen0_max_budget_from_config = gen0_max_size;
4424944229
#endif //FEATURE_EVENT_TRACE
4425044230
}
44231+
else
44232+
{
44233+
gen0_max_size =
44234+
#ifdef MULTIPLE_HEAPS
44235+
max ((size_t)6 * 1024 * 1024, min (Align(soh_segment_size / 2), (size_t)200 * 1024 * 1024));
44236+
#else //MULTIPLE_HEAPS
44237+
(
44238+
#ifdef BACKGROUND_GC
44239+
gc_can_use_concurrent ?
44240+
6 * 1024 * 1024 :
44241+
#endif //BACKGROUND_GC
44242+
max ((size_t)6 * 1024 * 1024, min (Align(soh_segment_size / 2), (size_t)200 * 1024 * 1024))
44243+
);
44244+
#endif //MULTIPLE_HEAPS
44245+
44246+
gen0_max_size = max (gen0_min_size, gen0_max_size);
44247+
44248+
if (heap_hard_limit)
44249+
{
44250+
size_t gen0_max_size_seg = soh_segment_size / 4;
44251+
dprintf (GTC_LOG, ("limit gen0 max %zd->%zd", gen0_max_size, gen0_max_size_seg));
44252+
gen0_max_size = min (gen0_max_size, gen0_max_size_seg);
44253+
}
44254+
}
4425144255

4425244256
gen0_max_size = Align (gen0_max_size);
4425344257
gen0_min_size = min (gen0_min_size, gen0_max_size);
@@ -44284,6 +44288,17 @@ void gc_heap::init_static_data()
4428444288
static_data_table[i][0].max_size = gen0_max_size;
4428544289
static_data_table[i][1].max_size = gen1_max_size;
4428644290
}
44291+
44292+
#ifdef DYNAMIC_HEAP_COUNT
44293+
if (gc_heap::dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes)
44294+
{
44295+
gc_heap::dynamic_heap_count_data.min_gen0_new_allocation = gen0_min_size;
44296+
if (gen0_max_size_config)
44297+
{
44298+
gc_heap::dynamic_heap_count_data.max_gen0_new_allocation = gen0_max_size;
44299+
}
44300+
}
44301+
#endif //DYNAMIC_HEAP_COUNT
4428744302
}
4428844303

4428944304
bool gc_heap::init_dynamic_data()
@@ -49735,13 +49750,43 @@ HRESULT GCHeap::Initialize()
4973549750
}
4973649751
// This should be adjusted based on the target tcp. See comments in gcpriv.h
4973749752
gc_heap::dynamic_heap_count_data.around_target_threshold = 10.0;
49738-
// This should really be set as part of computing static data and should take conserve_mem_setting into consideration.
49739-
gc_heap::dynamic_heap_count_data.max_gen0_new_allocation = Align (min (dd_max_size (gc_heap::g_heaps[0]->dynamic_data_of (0)), (size_t)(64 * 1024 * 1024)), get_alignment_constant (TRUE));
49740-
gc_heap::dynamic_heap_count_data.min_gen0_new_allocation = Align (dd_min_size (gc_heap::g_heaps[0]->dynamic_data_of (0)), get_alignment_constant (TRUE));
4974149753

49742-
dprintf (6666, ("datas max gen0 budget %Id, min %Id",
49743-
gc_heap::dynamic_heap_count_data.max_gen0_new_allocation, gc_heap::dynamic_heap_count_data.min_gen0_new_allocation));
49754+
int gen0_growth_soh_ratio_percent = (int)GCConfig::GetGCDGen0GrowthPercent();
49755+
if (gen0_growth_soh_ratio_percent)
49756+
{
49757+
gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_percent = (int)GCConfig::GetGCDGen0GrowthPercent() * 0.01f;
49758+
}
49759+
// You can specify what sizes you want to allow DATAS to stay within wrt the SOH stable size.
49760+
// By default DATAS allows 10x this size for gen0 budget when the size is small, and 0.1x when the size is large.
49761+
int gen0_growth_min_permil = (int)GCConfig::GetGCDGen0GrowthMinFactor();
49762+
int gen0_growth_max_permil = (int)GCConfig::GetGCDGen0GrowthMaxFactor();
49763+
if (gen0_growth_min_permil)
49764+
{
49765+
gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min = gen0_growth_min_permil * 0.001f;
49766+
}
49767+
if (gen0_growth_max_permil)
49768+
{
49769+
gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max = gen0_growth_max_permil * 0.001f;
49770+
}
49771+
49772+
if (gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min > gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max)
49773+
{
49774+
log_init_error_to_host ("DATAS min permil for gen0 growth %d is greater than max %d, it needs to be lower",
49775+
gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min, gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max);
49776+
return E_FAIL;
49777+
}
49778+
49779+
GCConfig::SetGCDTargetTCP ((int)gc_heap::dynamic_heap_count_data.target_tcp);
49780+
GCConfig::SetGCDGen0GrowthPercent ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_percent * 100.0f));
49781+
GCConfig::SetGCDGen0GrowthMinFactor ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min * 1000.0f));
49782+
GCConfig::SetGCDGen0GrowthMaxFactor ((int)(gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max * 1000.0f));
49783+
dprintf (6666, ("DATAS gen0 growth multiplier will be adjusted by %d%%, cap %.3f-%.3f, min budget %Id, max %Id",
49784+
(int)GCConfig::GetGCDGen0GrowthPercent(),
49785+
gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_min, gc_heap::dynamic_heap_count_data.gen0_growth_soh_ratio_max,
49786+
gc_heap::dynamic_heap_count_data.min_gen0_new_allocation, gc_heap::dynamic_heap_count_data.max_gen0_new_allocation));
4974449787
}
49788+
49789+
GCConfig::SetGCDynamicAdaptationMode (gc_heap::dynamic_adaptation_mode);
4974549790
#endif //DYNAMIC_HEAP_COUNT
4974649791
GCScan::GcRuntimeStructuresValid (TRUE);
4974749792

@@ -52280,13 +52325,11 @@ size_t gc_heap::get_gen0_min_size()
5228052325
gen0size = gen0size / 8 * 5;
5228152326
}
5228252327

52283-
#ifdef USE_REGIONS
5228452328
#ifdef STRESS_REGIONS
5228552329
// This is just so we can test allocation using more than one region on machines with very
5228652330
// small caches.
5228752331
gen0size = ((size_t)1 << min_segment_size_shr) * 3;
5228852332
#endif //STRESS_REGIONS
52289-
#endif //USE_REGIONS
5229052333

5229152334
gen0size = Align (gen0size);
5229252335

@@ -53883,6 +53926,8 @@ bool gc_heap::compute_memory_settings(bool is_initialization, uint32_t& nhp, uin
5388353926
m_high_memory_load_th = min ((high_memory_load_th + 5), v_high_memory_load_th);
5388453927
almost_high_memory_load_th = (high_memory_load_th > 5) ? (high_memory_load_th - 5) : 1; // avoid underflow of high_memory_load_th - 5
5388553928

53929+
GCConfig::SetGCHighMemPercent (high_memory_load_th);
53930+
5388653931
return true;
5388753932
}
5388853933

src/coreclr/gc/gcconfig.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class GCConfigStringHolder
9898
"prefixed by the CPU group number. Example: Unix - 1,3,5,7-9,12, Windows - 0:1,1:7-9") \
9999
INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \
100100
INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \
101-
INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \
101+
INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", "System.GC.Gen0MaxBudget", 0, "Specifies the largest gen0 allocation budget") \
102102
INT_CONFIG (GCGen1MaxBudget, "GCGen1MaxBudget", NULL, 0, "Specifies the largest gen1 allocation budget") \
103103
INT_CONFIG (GCLowSkipRatio, "GCLowSkipRatio", NULL, 30, "Specifies the low generation skip ratio") \
104104
INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \
@@ -144,6 +144,9 @@ class GCConfigStringHolder
144144
INT_CONFIG (GCDynamicAdaptationMode, "GCDynamicAdaptationMode", "System.GC.DynamicAdaptationMode", 1, "Enable the GC to dynamically adapt to application sizes.") \
145145
INT_CONFIG (GCDTargetTCP, "GCDTargetTCP", "System.GC.DTargetTCP", 0, "Specifies the target tcp for DATAS") \
146146
INT_CONFIG (GCDBGCRatio, "GCDBGCRatio", NULL, 0, "Specifies the ratio of BGC to NGC2 for HC change") \
147+
INT_CONFIG (GCDGen0GrowthPercent, "GCDGen0GrowthPercent", "System.GC.DGen0GrowthPercent", 0, "Specifies the percentage of the default growth factor") \
148+
INT_CONFIG (GCDGen0GrowthMinFactor, "GCDGen0GrowthMinFactor", "System.GC.DGen0GrowthMinFactor", 0, "Specifies the minimum growth factor in permil") \
149+
INT_CONFIG (GCDGen0GrowthMaxFactor, "GCDGen0GrowthMaxFactor", "System.GC.DGen0GrowthMaxFactor", 0, "Specifies the maximum growth factor in permil") \
147150
BOOL_CONFIG (GCCacheSizeFromSysConf, "GCCacheSizeFromSysConf", NULL, false, "Specifies using sysconf to retrieve the last level cache size for Unix.")
148151

149152
// This class is responsible for retreiving configuration information

src/coreclr/gc/gcpriv.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4388,6 +4388,18 @@ class gc_heap
43884388
float target_tcp = 2.0;
43894389
float target_gen2_tcp = 10.0;
43904390

4391+
// The following 3 constants are used in the computation for the total gen0 budget relative to the stable soh size.
4392+
//
4393+
// By default DATAS computes a multiplier (gen0_growth_soh_ratio) that scales the size. This multiplier follows
4394+
// a power decay curve where the multiplier decreases rapidly as the size increases. We cap it at 10x at the low
4395+
// end and 10% at the high end.
4396+
//
4397+
// You can choose to modify these by specifying gen0_growth_factor_percent to reduce or increase this multiplier
4398+
// and the min/max multipliers.
4399+
float gen0_growth_soh_ratio_percent = 1.0;
4400+
float gen0_growth_soh_ratio_min = 0.1f;
4401+
float gen0_growth_soh_ratio_max = 10.0;
4402+
43914403
static const int recorded_adjustment_size = 4;
43924404
static const int sample_size = 3;
43934405
static const int recorded_tcp_array_size = 64;
@@ -5069,23 +5081,23 @@ class gc_heap
50695081
// time in msl).
50705082
//
50715083

5072-
size_t max_gen0_new_allocation;
5073-
size_t min_gen0_new_allocation;
5084+
size_t max_gen0_new_allocation = 64 * 1024 * 1024;
5085+
size_t min_gen0_new_allocation = 0;
50745086

50755087
size_t compute_total_gen0_budget (size_t total_soh_stable_size)
50765088
{
50775089
assert (total_soh_stable_size > 0);
50785090

5079-
float factor = (float)(20 - conserve_mem_setting);
5080-
double old_gen_growth_factor = factor / sqrt ((double)total_soh_stable_size / 1000.0 / 1000.0);
5081-
double saved_old_gen_growth_factor = old_gen_growth_factor;
5082-
old_gen_growth_factor = min (10.0, old_gen_growth_factor);
5083-
old_gen_growth_factor = max (0.1, old_gen_growth_factor);
5091+
float factor = (float)(20 - conserve_mem_setting) * gen0_growth_soh_ratio_percent;
5092+
double gen0_growth_soh_ratio = factor / sqrt ((double)total_soh_stable_size / 1000.0 / 1000.0);
5093+
double saved_gen0_growth_soh_ratio = gen0_growth_soh_ratio;
5094+
gen0_growth_soh_ratio = min ((double)gen0_growth_soh_ratio_max, gen0_growth_soh_ratio);
5095+
gen0_growth_soh_ratio = max ((double)gen0_growth_soh_ratio_min, gen0_growth_soh_ratio);
50845096

5085-
size_t total_new_allocation_old_gen = (size_t)(old_gen_growth_factor * (double)total_soh_stable_size);
5097+
size_t total_new_allocation_old_gen = (size_t)(gen0_growth_soh_ratio * (double)total_soh_stable_size);
50865098
dprintf (6666, ("stable soh %Id (%.3fmb), factor %.3f=>%.3f -> total gen0 new_alloc %Id (%.3fmb)",
50875099
total_soh_stable_size, ((double)total_soh_stable_size / 1000.0 / 1000.0),
5088-
saved_old_gen_growth_factor, old_gen_growth_factor, total_new_allocation_old_gen,
5100+
saved_gen0_growth_soh_ratio, gen0_growth_soh_ratio, total_new_allocation_old_gen,
50895101
((double)total_new_allocation_old_gen / 1000.0 / 1000.0)));
50905102
return total_new_allocation_old_gen;
50915103
}

0 commit comments

Comments
 (0)