From ebeab20491f1ec703c01fc04abd3d6f00be70d59 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:19:12 -0700 Subject: [PATCH 1/8] fix lower heap hard limit condition for regions --- src/coreclr/gc/gc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index d603eda9ef2b0..2106db380ae04 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44895,10 +44895,13 @@ HRESULT GCHeap::Initialize() { if (gc_heap::heap_hard_limit) { - gc_heap::regions_range = 2 * gc_heap::heap_hard_limit; + // Keep the reservation size for regions similar to that for segments. + // We will initially reserve 6x the configured hard limit + gc_heap::regions_range = 6 * gc_heap::heap_hard_limit; } else { + // If no hard_limit is configured the reservation size is max of 256gb or 2x physical limit gc_heap::regions_range = max(((size_t)256 * 1024 * 1024 * 1024), (size_t)(2 * gc_heap::total_physical_mem)); } gc_heap::regions_range = align_on_page(gc_heap::regions_range); From 6eaf767a02e8df36f6b9034b2996641b7f37d405 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Thu, 29 Sep 2022 22:20:29 -0700 Subject: [PATCH 2/8] adjust region sizes based on individual heap sizes --- src/coreclr/gc/gc.cpp | 15 ++++++++++++++- src/coreclr/gc/gcconfig.h | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 2106db380ae04..d5c5ac999ef99 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44897,7 +44897,7 @@ HRESULT GCHeap::Initialize() { // Keep the reservation size for regions similar to that for segments. // We will initially reserve 6x the configured hard limit - gc_heap::regions_range = 6 * gc_heap::heap_hard_limit; + gc_heap::regions_range = 2 * gc_heap::heap_hard_limit; } else { @@ -45052,6 +45052,19 @@ HRESULT GCHeap::Initialize() #ifdef USE_REGIONS gc_heap::enable_special_regions_p = (bool)GCConfig::GetGCEnableSpecialRegions(); size_t gc_region_size = (size_t)GCConfig::GetGCRegionSize(); + + // Adjust GCRegionSize based on how large each heap would be, for smaller heaps we would + // like to keep Region sizes small. We choose between 1 (< 64mb), 2 (<128mb) and 4mb (>128mb) + // by default (unless its configured explictly). + if (gc_region_size == 0){ + if (gc_heap::regions_range / nhp >= (128 * 1024 * 1024)){ + gc_region_size = 4 * 1024 * 1024; + } else if (gc_heap::regions_range / nhp >= (64 * 1024 * 1024)){ + gc_region_size = 2 * 1024 * 1024; + } else + gc_region_size = 1 * 1024 * 1024; + } + if (!power_of_two_p(gc_region_size) || ((gc_region_size * nhp * 19) > gc_heap::regions_range)) { return E_OUTOFMEMORY; diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h index 532a6998c0bc6..2b5f87b41f4cc 100644 --- a/src/coreclr/gc/gcconfig.h +++ b/src/coreclr/gc/gcconfig.h @@ -104,7 +104,7 @@ class GCConfigStringHolder INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \ INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \ INT_CONFIG (GCRegionRange, "GCRegionRange", NULL, 0, "Specifies the range for the GC heap") \ - INT_CONFIG (GCRegionSize, "GCRegionSize", NULL, 4194304, "Specifies the size for a basic GC region") \ + INT_CONFIG (GCRegionSize, "GCRegionSize", NULL, 0, "Specifies the size for a basic GC region") \ INT_CONFIG (GCEnableSpecialRegions, "GCEnableSpecialRegions", NULL, 0, "Specifies to enable special handling some regions like SIP") \ STRING_CONFIG(LogFile, "GCLogFile", NULL, "Specifies the name of the GC log file") \ STRING_CONFIG(ConfigLogFile, "GCConfigLogFile", NULL, "Specifies the name of the GC config log file") \ From 8c095e2e6d3959eb920699cd8ff67266b473ca78 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Thu, 29 Sep 2022 22:24:26 -0700 Subject: [PATCH 3/8] updated comment --- src/coreclr/gc/gc.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index d5c5ac999ef99..752c252f67801 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44894,9 +44894,8 @@ HRESULT GCHeap::Initialize() if (gc_heap::regions_range == 0) { if (gc_heap::heap_hard_limit) - { - // Keep the reservation size for regions similar to that for segments. - // We will initially reserve 6x the configured hard limit + { + // We will initially reserve 2x the configured hard limit gc_heap::regions_range = 2 * gc_heap::heap_hard_limit; } else From a41bff2ce5a15634f8e078c19691d77a13aadd01 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Fri, 30 Sep 2022 09:50:52 -0700 Subject: [PATCH 4/8] more tuning --- src/coreclr/gc/gc.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 752c252f67801..ba4d929afc1a5 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44895,8 +44895,10 @@ HRESULT GCHeap::Initialize() { if (gc_heap::heap_hard_limit) { - // We will initially reserve 2x the configured hard limit - gc_heap::regions_range = 2 * gc_heap::heap_hard_limit; + // We will initially reserve 5x the configured hard limit and 2x if + // large pages are enabled + gc_heap::regions_range = (gc_heap::use_large_pages_p) ? 2 * gc_heap::heap_hard_limit // large pages + : 5 * gc_heap::heap_hard_limit; } else { @@ -45053,12 +45055,12 @@ HRESULT GCHeap::Initialize() size_t gc_region_size = (size_t)GCConfig::GetGCRegionSize(); // Adjust GCRegionSize based on how large each heap would be, for smaller heaps we would - // like to keep Region sizes small. We choose between 1 (< 64mb), 2 (<128mb) and 4mb (>128mb) - // by default (unless its configured explictly). + // like to keep Region sizes small. We choose between 4, 2 and 4mb based on the calculations + // below (unless its configured explictly). if (gc_region_size == 0){ - if (gc_heap::regions_range / nhp >= (128 * 1024 * 1024)){ + if (gc_heap::regions_range / nhp / 19 >= (4 * 1024 * 1024)){ gc_region_size = 4 * 1024 * 1024; - } else if (gc_heap::regions_range / nhp >= (64 * 1024 * 1024)){ + } else if (gc_heap::regions_range / nhp / 19 >= (2 * 1024 * 1024)){ gc_region_size = 2 * 1024 * 1024; } else gc_region_size = 1 * 1024 * 1024; From 13bf5ddc4df0efeec1eed7c11e167e48ad51ed78 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Fri, 30 Sep 2022 12:45:35 -0700 Subject: [PATCH 5/8] on more tuning update. --- src/coreclr/gc/gc.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index ba4d929afc1a5..6ba89ef1a69eb 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -45055,12 +45055,13 @@ HRESULT GCHeap::Initialize() size_t gc_region_size = (size_t)GCConfig::GetGCRegionSize(); // Adjust GCRegionSize based on how large each heap would be, for smaller heaps we would - // like to keep Region sizes small. We choose between 4, 2 and 4mb based on the calculations - // below (unless its configured explictly). + // like to keep Region sizes small. We choose between 4, 2 and 1mb based on the calculations + // below (unless its configured explictly) such that there are at least 2 regions available + // except for the smallest case. Now the lowest limit possible is 4mb. if (gc_region_size == 0){ - if (gc_heap::regions_range / nhp / 19 >= (4 * 1024 * 1024)){ + if ((gc_heap::regions_range / nhp / 19) / 2 >= (4 * 1024 * 1024)){ gc_region_size = 4 * 1024 * 1024; - } else if (gc_heap::regions_range / nhp / 19 >= (2 * 1024 * 1024)){ + } else if ((gc_heap::regions_range / nhp / 19) / 2 >= (2 * 1024 * 1024)){ gc_region_size = 2 * 1024 * 1024; } else gc_region_size = 1 * 1024 * 1024; From 8ceb001f3ec44981d6a26e4e8499387d058e0d0c Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Sun, 2 Oct 2022 19:29:26 -0700 Subject: [PATCH 6/8] fixing the case for per heap hard_limit and some styling changes. --- src/coreclr/gc/gc.cpp | 36 +++++++++++++++++++++++++----------- src/coreclr/gc/gcpriv.h | 2 ++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 6ba89ef1a69eb..04cd5c512affa 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44894,11 +44894,18 @@ HRESULT GCHeap::Initialize() if (gc_heap::regions_range == 0) { if (gc_heap::heap_hard_limit) - { - // We will initially reserve 5x the configured hard limit and 2x if - // large pages are enabled - gc_heap::regions_range = (gc_heap::use_large_pages_p) ? 2 * gc_heap::heap_hard_limit // large pages - : 5 * gc_heap::heap_hard_limit; + { + if (gc_heap::heap_hard_limit_oh[soh]) + { + gc_heap::regions_range = gc_heap::heap_hard_limit; + } + else + { + // We will initially reserve 5x the configured hard limit and 2x if + // large pages are enabled as this is closer to segments + gc_heap::regions_range = ((gc_heap::use_large_pages_p) ? (2 * gc_heap::heap_hard_limit) // large pages + : (5 * gc_heap::heap_hard_limit)); + } } else { @@ -45058,16 +45065,23 @@ HRESULT GCHeap::Initialize() // like to keep Region sizes small. We choose between 4, 2 and 1mb based on the calculations // below (unless its configured explictly) such that there are at least 2 regions available // except for the smallest case. Now the lowest limit possible is 4mb. - if (gc_region_size == 0){ - if ((gc_heap::regions_range / nhp / 19) / 2 >= (4 * 1024 * 1024)){ + if (gc_region_size == 0) + { + if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (4 * 1024 * 1024)) + { gc_region_size = 4 * 1024 * 1024; - } else if ((gc_heap::regions_range / nhp / 19) / 2 >= (2 * 1024 * 1024)){ + } + else if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (2 * 1024 * 1024)) + { gc_region_size = 2 * 1024 * 1024; - } else - gc_region_size = 1 * 1024 * 1024; + } + else + { + gc_region_size = 1 * 1024 * 1024; + } } - if (!power_of_two_p(gc_region_size) || ((gc_region_size * nhp * 19) > gc_heap::regions_range)) + if (!power_of_two_p(gc_region_size) || ((gc_region_size * nhp * min_regions_per_heap) > gc_heap::regions_range)) { return E_OUTOFMEMORY; } diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 45f266259c62d..084fa0ba925d5 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -5807,6 +5807,8 @@ class heap_segment #define region_alloc_free_bit (1 << (sizeof (uint32_t) * 8 - 1)) +const int min_regions_per_heap = ((ephemeral_generation_count + 1) + ((total_generation_count - uoh_start_generation) * LARGE_REGION_FACTOR)); + enum allocate_direction { allocate_forward = 1, From 5ebfcb223dd6cc35a3a3ec538c381861310991d9 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Mon, 3 Oct 2022 16:34:48 -0700 Subject: [PATCH 7/8] CR updates --- src/coreclr/gc/gc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 04cd5c512affa..1dea543a0cc4d 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -44901,9 +44901,8 @@ HRESULT GCHeap::Initialize() } else { - // We will initially reserve 5x the configured hard limit and 2x if - // large pages are enabled as this is closer to segments - gc_heap::regions_range = ((gc_heap::use_large_pages_p) ? (2 * gc_heap::heap_hard_limit) // large pages + // We use this calculation because it's close to what we used for segments. + gc_heap::regions_range = ((gc_heap::use_large_pages_p) ? (2 * gc_heap::heap_hard_limit) : (5 * gc_heap::heap_hard_limit)); } } @@ -45067,6 +45066,8 @@ HRESULT GCHeap::Initialize() // except for the smallest case. Now the lowest limit possible is 4mb. if (gc_region_size == 0) { + // We have a minimum amount of basic regions we have to fit per heap, and we'd like to have the initial + // regions only take up half of the space. if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (4 * 1024 * 1024)) { gc_region_size = 4 * 1024 * 1024; From ed6da61e91560c15f9076e8c859de70312cb2a0c Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Tue, 4 Oct 2022 11:44:55 -0700 Subject: [PATCH 8/8] small refactor oversight from the main PR. --- src/coreclr/gc/gc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 1dea543a0cc4d..0f6318ba8f8cf 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -45068,11 +45068,12 @@ HRESULT GCHeap::Initialize() { // We have a minimum amount of basic regions we have to fit per heap, and we'd like to have the initial // regions only take up half of the space. - if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (4 * 1024 * 1024)) + size_t max_region_size = gc_heap::regions_range / 2 / nhp / min_regions_per_heap; + if (max_region_size >= (4 * 1024 * 1024)) { gc_region_size = 4 * 1024 * 1024; } - else if ((gc_heap::regions_range / nhp / min_regions_per_heap) / 2 >= (2 * 1024 * 1024)) + else if (max_region_size >= (2 * 1024 * 1024)) { gc_region_size = 2 * 1024 * 1024; }