wingo pushed a commit to branch wip-whippet in repository guile. commit b2f4083f913d8b155cafe0cdc986b34dbf96fb05 Author: Andy Wingo <wi...@igalia.com> AuthorDate: Thu Aug 7 11:40:17 2025 +0200
Change growable heap sizer to use sqrt sizing Instead of heap-size-multiplier, it's heap-double-threshold: the heap size at which there is a 2x multiplier of live data. --- api/gc-options.h | 2 +- src/gc-options-internal.h | 2 +- src/gc-options.c | 4 ++-- src/growable-heap-sizer.h | 27 +++++++++++++++------------ src/heap-sizer.h | 2 +- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/api/gc-options.h b/api/gc-options.h index 2f3f7f792..609b350bd 100644 --- a/api/gc-options.h +++ b/api/gc-options.h @@ -13,7 +13,7 @@ enum { GC_OPTION_HEAP_SIZE_POLICY, GC_OPTION_HEAP_SIZE, GC_OPTION_MAXIMUM_HEAP_SIZE, - GC_OPTION_HEAP_SIZE_MULTIPLIER, + GC_OPTION_HEAP_DOUBLE_THRESHOLD, GC_OPTION_HEAP_EXPANSIVENESS, GC_OPTION_PARALLELISM }; diff --git a/src/gc-options-internal.h b/src/gc-options-internal.h index 9e9fbca22..ac0d7e704 100644 --- a/src/gc-options-internal.h +++ b/src/gc-options-internal.h @@ -11,7 +11,7 @@ struct gc_common_options { enum gc_heap_size_policy heap_size_policy; size_t heap_size; size_t maximum_heap_size; - double heap_size_multiplier; + double heap_double_threshold; double heap_expansiveness; int parallelism; }; diff --git a/src/gc-options.c b/src/gc-options.c index 31de02745..07d8fdd37 100644 --- a/src/gc-options.c +++ b/src/gc-options.c @@ -19,12 +19,12 @@ #define FOR_EACH_SIZE_GC_OPTION(M) \ M(HEAP_SIZE, heap_size, "heap-size", \ size, size, 6 * 1024 * 1024, 0, -1) \ + M(HEAP_DOUBLE_THRESHOLD, heap_double_threshold, "heap-double-threshold", \ + size, size, 60 * 1024 * 1024, 1, -1) \ M(MAXIMUM_HEAP_SIZE, maximum_heap_size, "maximum-heap-size", \ size, size, 0, 0, -1) #define FOR_EACH_DOUBLE_GC_OPTION(M) \ - M(HEAP_SIZE_MULTIPLIER, heap_size_multiplier, "heap-size-multiplier", \ - double, double, 1.75, 1.0, 1e6) \ M(HEAP_EXPANSIVENESS, heap_expansiveness, "heap-expansiveness", \ double, double, 1.0, 0.0, 50.0) diff --git a/src/growable-heap-sizer.h b/src/growable-heap-sizer.h index 1ac761660..90f7ba632 100644 --- a/src/growable-heap-sizer.h +++ b/src/growable-heap-sizer.h @@ -1,6 +1,7 @@ #ifndef GROWABLE_HEAP_SIZER_H #define GROWABLE_HEAP_SIZER_H +#include <math.h> #include <pthread.h> #include <stdlib.h> #include <string.h> @@ -9,29 +10,30 @@ #include "heap-sizer.h" // This is a simple heap-sizing algorithm that will grow the heap if it is -// smaller than a given multiplier of the live data size. It does not shrink -// the heap. +// smaller than a multiplier of the live data size, where the multiplier depends +// on the square root of the live data size. It does not shrink the heap. struct gc_growable_heap_sizer { struct gc_heap *heap; - double multiplier; + double sqrt_multiplier; pthread_mutex_t lock; }; static void -gc_growable_heap_sizer_set_multiplier(struct gc_growable_heap_sizer *sizer, - double multiplier) { +gc_growable_heap_sizer_set_double_threshold(struct gc_growable_heap_sizer *sizer, + size_t threshold) { pthread_mutex_lock(&sizer->lock); - sizer->multiplier = multiplier; + GC_ASSERT(threshold); + sizer->sqrt_multiplier = sqrt(threshold / 2); pthread_mutex_unlock(&sizer->lock); } static size_t gc_growable_heap_sizer_target_size(struct gc_growable_heap_sizer *sizer, size_t heap_size, size_t live_bytes) { - pthread_mutex_lock(&sizer->lock); - size_t target_size = live_bytes * sizer->multiplier; - pthread_mutex_unlock(&sizer->lock); + size_t target_size = live_bytes; + if (live_bytes) + target_size += sqrt(live_bytes) * sizer->sqrt_multiplier; return target_size; } @@ -41,7 +43,8 @@ gc_growable_heap_sizer_on_gc(struct gc_growable_heap_sizer *sizer, uint64_t pause_ns, void (*set_heap_size)(struct gc_heap*, size_t)) { pthread_mutex_lock(&sizer->lock); - size_t target_size = live_bytes * sizer->multiplier; + size_t target_size = + gc_growable_heap_sizer_target_size(sizer, heap_size, live_bytes); if (target_size > heap_size) { fprintf(stderr, "resize (multiplier): %zu -> %zu\n", heap_size, target_size); set_heap_size(sizer->heap, target_size); @@ -50,15 +53,15 @@ gc_growable_heap_sizer_on_gc(struct gc_growable_heap_sizer *sizer, } static struct gc_growable_heap_sizer* -gc_make_growable_heap_sizer(struct gc_heap *heap, double multiplier) { +gc_make_growable_heap_sizer(struct gc_heap *heap, size_t threshold) { struct gc_growable_heap_sizer *sizer; sizer = malloc(sizeof(*sizer)); if (!sizer) GC_CRASH(); memset(sizer, 0, sizeof(*sizer)); sizer->heap = heap; - sizer->multiplier = multiplier; pthread_mutex_init(&sizer->lock, NULL); + gc_growable_heap_sizer_set_double_threshold(sizer, threshold); return sizer; } diff --git a/src/heap-sizer.h b/src/heap-sizer.h index 9515a51c8..194c284e7 100644 --- a/src/heap-sizer.h +++ b/src/heap-sizer.h @@ -28,7 +28,7 @@ gc_make_heap_sizer(struct gc_heap *heap, case GC_HEAP_SIZE_GROWABLE: ret.growable = - gc_make_growable_heap_sizer(heap, options->heap_size_multiplier); + gc_make_growable_heap_sizer(heap, options->heap_double_threshold); break; case GC_HEAP_SIZE_ADAPTIVE: