mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-15 16:20:17 +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:
parent
70a95005c0
commit
8fef55a81c
1 changed files with 39 additions and 38 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue