From: Vlad Brezae Date: Fri, 7 Apr 2017 23:21:48 +0000 (+0300) Subject: [sgen] Resize nursery according also to pause times X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=5c74ddb92de7e5ac9f534abd4ff50a7c692e38fc [sgen] Resize nursery according also to pause times --- diff --git a/mono/sgen/sgen-conf.h b/mono/sgen/sgen-conf.h index 324009cc295..63e922c470e 100644 --- a/mono/sgen/sgen-conf.h +++ b/mono/sgen/sgen-conf.h @@ -211,4 +211,12 @@ typedef mword SgenDescriptor; #define SGEN_DEFAULT_NURSERY_SIZE (1 << 22) #define SGEN_DEFAULT_NURSERY_MAX_SIZE (1 << 25) +/* + * We are trying to keep pauses lower than this (ms). We use it for dynamic nursery + * sizing heuristics. We are keeping leeway in order to be prepared for work-load + * variations. + */ +#define SGEN_MAX_PAUSE_TIME 30 +#define SGEN_MAX_PAUSE_MARGIN 0.66f + #endif diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 9f8a8aa63ff..2c0337d6a35 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -288,6 +288,9 @@ static guint64 time_major_fragment_creation = 0; static guint64 time_max = 0; +static int sgen_max_pause_time = SGEN_MAX_PAUSE_TIME; +static float sgen_max_pause_margin = SGEN_MAX_PAUSE_MARGIN; + static SGEN_TV_DECLARE (time_major_conc_collection_start); static SGEN_TV_DECLARE (time_major_conc_collection_end); @@ -1612,6 +1615,7 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ SgenGrayQueue gc_thread_gray_queue; SgenObjectOperations *object_ops_nopar, *object_ops_par = NULL; ScanCopyContext ctx; + int duration; TV_DECLARE (atv); TV_DECLARE (btv); SGEN_TV_DECLARE (last_minor_collection_start_tv); @@ -1743,7 +1747,13 @@ collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_ if (remset_consistency_checks) sgen_check_remset_consistency (); - sgen_resize_nursery (); + + TV_GETTIME (btv); + duration = (int)(TV_ELAPSED (last_minor_collection_start_tv, btv) / 10000); + if (duration > (sgen_max_pause_time * sgen_max_pause_margin)) + sgen_resize_nursery (TRUE); + else + sgen_resize_nursery (FALSE); /* walk the pin_queue, build up the fragment list of free memory, unmark * pinned objects as we go, memzero() the empty fragments so they are ready for the diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index 1a727a6d333..27727a537b6 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -897,7 +897,7 @@ void sgen_los_mark_mod_union_card (GCObject *mono_obj, void **ptr); void sgen_clear_nursery_fragments (void); void sgen_nursery_allocator_prepare_for_pinning (void); void sgen_nursery_allocator_set_nursery_bounds (char *nursery_start, size_t min_size, size_t max_size); -void sgen_resize_nursery (void); +void sgen_resize_nursery (gboolean need_shrink); mword sgen_build_nursery_fragments (GCMemSection *nursery_section, SgenGrayQueue *unpin_queue); void sgen_init_nursery_allocator (void); void sgen_nursery_allocator_init_heavy_stats (void); diff --git a/mono/sgen/sgen-nursery-allocator.c b/mono/sgen/sgen-nursery-allocator.c index 1452b6b7d79..53a7999a74e 100644 --- a/mono/sgen/sgen-nursery-allocator.c +++ b/mono/sgen/sgen-nursery-allocator.c @@ -920,7 +920,7 @@ sgen_nursery_allocator_set_nursery_bounds (char *start, size_t min_size, size_t } void -sgen_resize_nursery (void) +sgen_resize_nursery (gboolean need_shrink) { size_t major_size; @@ -938,11 +938,11 @@ sgen_resize_nursery (void) * section). */ if ((sgen_nursery_size * 2) < (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) && - (sgen_nursery_size * 2) <= sgen_nursery_max_size) { + (sgen_nursery_size * 2) <= sgen_nursery_max_size && !need_shrink) { if ((nursery_section->end_data - nursery_section->data) == sgen_nursery_size) nursery_section->end_data += sgen_nursery_size; sgen_nursery_size *= 2; - } else if (sgen_nursery_size > (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) && + } else if ((sgen_nursery_size > (major_size / SGEN_DEFAULT_ALLOWANCE_NURSERY_SIZE_RATIO) || need_shrink) && (sgen_nursery_size / 2) >= sgen_nursery_min_size) { sgen_nursery_size /= 2; }