1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-14 23:50:19 +02:00

* gc.c, gc.h (SCM_MIN_YIELD_1, SCM_MIN_YIELD_2,

min_yield_fraction, min_yield, adjust_min_yield): Renamed from
SCM_GC_TRIGGER_1, SCM_GC_TRIGGER_2, gc_trigger_fraction,
gc_trigger, adjust_gc_trigger.

* gc.c (SCM_INIT_HEAP_SIZE_1, SCM_GC_TRIGGER_1, SCM_GC_TRIGGER_2):
Adjusted to 45000 cells, 40% and 40%.  Gives quick startup
without extra heap allocation.
This commit is contained in:
Mikael Djurfeldt 2000-03-21 03:57:53 +00:00
parent 70a95005c0
commit 8fef55a81c

View file

@ -114,16 +114,22 @@
* work around a oscillation that caused almost constant GC.] * work around a oscillation that caused almost constant GC.]
*/ */
#define SCM_INIT_HEAP_SIZE_1 (50000L * sizeof (scm_cell)) /*
* Heap size 45000 and 40% min yield gives quick startup and no extra
* heap allocation. Having higher values on min yield may lead to
* large heaps, especially if code behaviour is varying its
* maximum consumption between different freelists.
*/
#define SCM_INIT_HEAP_SIZE_1 (45000L * sizeof (scm_cell))
#define SCM_CLUSTER_SIZE_1 2000L #define SCM_CLUSTER_SIZE_1 2000L
#define SCM_GC_TRIGGER_1 -45 #define SCM_MIN_YIELD_1 40
#define SCM_INIT_HEAP_SIZE_2 (2500L * 2 * sizeof (scm_cell)) #define SCM_INIT_HEAP_SIZE_2 (2500L * 2 * sizeof (scm_cell))
#define SCM_CLUSTER_SIZE_2 1000L #define SCM_CLUSTER_SIZE_2 1000L
/* The following value may seem large, but note that if we get to GC at /* The following value may seem large, but note that if we get to GC at
* all, this means that we have a numerically intensive application * all, this means that we have a numerically intensive application
*/ */
#define SCM_GC_TRIGGER_2 -45 #define SCM_MIN_YIELD_2 40
#define SCM_MAX_SEGMENT_SIZE 2097000L /* a little less (adm) than 2 Mb */ #define SCM_MAX_SEGMENT_SIZE 2097000L /* a little less (adm) than 2 Mb */
@ -181,22 +187,22 @@ typedef struct scm_freelist_t {
unsigned int left_to_collect; unsigned int left_to_collect;
/* number of clusters which have been allocated */ /* number of clusters which have been allocated */
unsigned int clusters_allocated; unsigned int clusters_allocated;
/* a list of freelists, each of size gc_trigger, /* a list of freelists, each of size cluster_size,
except the last one which may be shorter */ * except the last one which may be shorter
*/
SCM clusters; SCM clusters;
SCM *clustertail; SCM *clustertail;
/* this is the number of objects in each cluster, including the spine cell */ /* this is the number of objects in each cluster, including the spine cell */
int cluster_size; int cluster_size;
/* set to grow the heap when we run out of clusters /* indicates that we should grow heap instead of GC:ing
*/ */
int grow_heap_p; int grow_heap_p;
/* minimum number of objects allocated before GC is triggered /* minimum yield on this list in order not to grow the heap
*/ */
long gc_trigger; long min_yield;
/* defines gc_trigger as percent of heap size /* defines min_yield as percent of total heap size
* 0 => constant trigger
*/ */
int gc_trigger_fraction; int min_yield_fraction;
#endif #endif
/* number of cells per object on this list */ /* number of cells per object on this list */
int span; int span;
@ -789,12 +795,12 @@ SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
#ifdef GUILE_NEW_GC_SCHEME #ifdef GUILE_NEW_GC_SCHEME
static void static void
adjust_gc_trigger (scm_freelist_t *freelist) adjust_min_yield (scm_freelist_t *freelist)
{ {
/* GC trigger is adjusted upwards so that next predicted total yield /* min yield is adjusted upwards so that next predicted total yield
* (allocated cells actually freed by GC) becomes * (allocated cells actually freed by GC) becomes
* `gc_trigger_fraction' of total heap size. Note, however, that * `min_yield_fraction' of total heap size. Note, however, that
* the absolute value of gc_trigger will correspond to `collected' * the absolute value of min_yield will correspond to `collected'
* on one master (the one which currently is triggering GC). * on one master (the one which currently is triggering GC).
* *
* The reason why we look at total yield instead of cells collected * The reason why we look at total yield instead of cells collected
@ -805,18 +811,18 @@ adjust_gc_trigger (scm_freelist_t *freelist)
* (We might consider computing a better prediction, for example * (We might consider computing a better prediction, for example
* by computing an average over multiple GC:s.) * by computing an average over multiple GC:s.)
*/ */
if (freelist->gc_trigger_fraction) if (freelist->min_yield_fraction)
{ {
/* Pick largest of last two yields. */ /* Pick largest of last two yields. */
int delta = ((SCM_HEAP_SIZE * freelist->gc_trigger_fraction / 100) int delta = ((SCM_HEAP_SIZE * freelist->min_yield_fraction / 100)
- SCM_MAX (scm_gc_yield_1, scm_gc_yield)); - (long) SCM_MAX (scm_gc_yield_1, scm_gc_yield));
#ifdef DEBUGINFO #ifdef DEBUGINFO
fprintf (stderr, " after GC = %d, delta = %d\n", fprintf (stderr, " after GC = %d, delta = %d\n",
scm_cells_allocated, scm_cells_allocated,
delta); delta);
#endif #endif
if (delta > 0) if (delta > 0)
freelist->gc_trigger += delta; freelist->min_yield += delta;
} }
} }
@ -847,7 +853,7 @@ scm_gc_for_newcell (scm_freelist_t *master, SCM *freelist)
+ master_cells_allocated (&scm_master_freelist2)); + master_cells_allocated (&scm_master_freelist2));
#endif #endif
scm_igc ("cells"); scm_igc ("cells");
adjust_gc_trigger (master); adjust_min_yield (master);
} }
} }
cell = SCM_CAR (master->clusters); cell = SCM_CAR (master->clusters);
@ -1564,15 +1570,15 @@ gc_sweep_freelist_finish (scm_freelist_t *freelist)
} }
scm_gc_cells_collected += freelist->collected; scm_gc_cells_collected += freelist->collected;
/* Although freelist->gc_trigger is used to test freelist->collected /* Although freelist->min_yield is used to test freelist->collected
* (which is the local GC yield for freelist), it is adjusted so * (which is the local GC yield for freelist), it is adjusted so
* that *total* yield is freelist->gc_trigger_fraction of total heap * that *total* yield is freelist->min_yield_fraction of total heap
* size. This means that a too low yield is compensated by more * size. This means that a too low yield is compensated by more
* heap on the list which is currently doing most work, which is * heap on the list which is currently doing most work, which is
* just what we want. * just what we want.
*/ */
collected = SCM_MAX (freelist->collected_1, freelist->collected); collected = SCM_MAX (freelist->collected_1, freelist->collected);
freelist->grow_heap_p = (collected < freelist->gc_trigger); freelist->grow_heap_p = (collected < freelist->min_yield);
} }
#endif #endif
@ -2345,13 +2351,13 @@ alloc_some_heap (scm_freelist_t *freelist)
* y + dh > f * (h + dh) * y + dh > f * (h + dh)
* *
* y : yield * y : yield
* f : GC trigger fraction * f : min yield fraction
* h : heap size * h : heap size
* dh : size of new heap segment * dh : size of new heap segment
* *
* This gives dh > (f * h - y) / (1 - f) * This gives dh > (f * h - y) / (1 - f)
*/ */
int f = freelist->gc_trigger_fraction; int f = freelist->min_yield_fraction;
long h = SCM_HEAP_SIZE; long h = SCM_HEAP_SIZE;
long min_cells = (f * h - 100 * (long) scm_gc_yield) / (99 - f); long min_cells = (f * h - 100 * (long) scm_gc_yield) / (99 - f);
len = SCM_EXPHEAP (freelist->heap_size); len = SCM_EXPHEAP (freelist->heap_size);
@ -2577,10 +2583,10 @@ make_initial_segment (scm_sizet init_heap_size, scm_freelist_t *freelist)
scm_expmem = 1; scm_expmem = 1;
#ifdef GUILE_NEW_GC_SCHEME #ifdef GUILE_NEW_GC_SCHEME
if (freelist->gc_trigger_fraction) if (freelist->min_yield_fraction)
freelist->gc_trigger = (freelist->heap_size * freelist->gc_trigger_fraction freelist->min_yield = (freelist->heap_size * freelist->min_yield_fraction
/ 100); / 100);
freelist->grow_heap_p = (freelist->heap_size < freelist->gc_trigger); freelist->grow_heap_p = (freelist->heap_size < freelist->min_yield);
#endif #endif
return 0; return 0;
@ -2592,19 +2598,14 @@ static void
init_freelist (scm_freelist_t *freelist, init_freelist (scm_freelist_t *freelist,
int span, int span,
int cluster_size, int cluster_size,
int gc_trigger) int min_yield)
{ {
freelist->clusters = SCM_EOL; freelist->clusters = SCM_EOL;
freelist->cluster_size = cluster_size + 1; freelist->cluster_size = cluster_size + 1;
freelist->left_to_collect = 0; freelist->left_to_collect = 0;
freelist->clusters_allocated = 0; freelist->clusters_allocated = 0;
if (gc_trigger < 0) freelist->min_yield = 0;
freelist->gc_trigger_fraction = - gc_trigger; freelist->min_yield_fraction = min_yield;
else
{
freelist->gc_trigger = gc_trigger;
freelist->gc_trigger_fraction = 0;
}
freelist->span = span; freelist->span = span;
freelist->collected = 0; freelist->collected = 0;
freelist->collected_1 = 0; freelist->collected_1 = 0;
@ -2637,10 +2638,10 @@ scm_init_storage (scm_sizet init_heap_size_1, scm_sizet init_heap_size_2)
scm_freelist2 = SCM_EOL; scm_freelist2 = SCM_EOL;
init_freelist (&scm_master_freelist, init_freelist (&scm_master_freelist,
1, SCM_CLUSTER_SIZE_1, 1, SCM_CLUSTER_SIZE_1,
gc_trigger_1 ? gc_trigger_1 : SCM_GC_TRIGGER_1); gc_trigger_1 ? gc_trigger_1 : SCM_MIN_YIELD_1);
init_freelist (&scm_master_freelist2, init_freelist (&scm_master_freelist2,
2, SCM_CLUSTER_SIZE_2, 2, SCM_CLUSTER_SIZE_2,
gc_trigger_2 ? gc_trigger_2 : SCM_GC_TRIGGER_2); gc_trigger_2 ? gc_trigger_2 : SCM_MIN_YIELD_2);
scm_max_segment_size scm_max_segment_size
= max_segment_size ? max_segment_size : SCM_MAX_SEGMENT_SIZE; = max_segment_size ? max_segment_size : SCM_MAX_SEGMENT_SIZE;
#else #else