Commit 085d1c54 authored by simonmar's avatar simonmar

[project @ 2005-07-25 13:59:09 by simonmar]

Tweaks to the GC to improve perforrmance.  Might be as much as 10% on
some programs.
parent a91e3166
......@@ -62,12 +62,18 @@ typedef struct step_ {
unsigned int n_large_blocks; /* no. of blocks used by large objs */
int is_compacted; /* compact this step? (old gen only) */
/* During GC, if we are collecting this step, blocks and n_blocks
* are copied into the following two fields. After GC, these blocks
* are freed. */
bdescr * old_blocks; /* bdescr of first from-space block */
unsigned int n_old_blocks; /* number of blocks in from-space */
/* temporary use during GC: */
StgPtr hp; /* next free locn in to-space */
StgPtr hpLim; /* end of current to-space block */
bdescr * hp_bd; /* bdescr of current to-space block */
bdescr * to_blocks; /* bdescr of first to-space block */
unsigned int n_to_blocks; /* number of blocks in to-space */
StgPtr scavd_hp; /* ... same as above, but already */
StgPtr scavd_hpLim; /* scavenged. */
bdescr * scan_bd; /* block currently being scanned */
StgPtr scan; /* scan pointer in current block */
bdescr * new_large_objects; /* large objects collected so far */
......
This diff is collapsed.
......@@ -842,7 +842,7 @@ update_bkwd_compact( step *stp )
StgInfoTable *info;
nat size, free_blocks;
bd = free_bd = stp->blocks;
bd = free_bd = stp->old_blocks;
free = free_bd->start;
free_blocks = 1;
......@@ -917,7 +917,7 @@ update_bkwd_compact( step *stp )
freeChain(free_bd->link);
free_bd->link = NULL;
}
stp->n_blocks = free_blocks;
stp->n_old_blocks = free_blocks;
return free_blocks;
}
......@@ -976,25 +976,26 @@ compact( void (*get_roots)(evac_fn) )
// 2. update forward ptrs
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
for (s = 0; s < generations[g].n_steps; s++) {
if (g==0 && s ==0) continue;
stp = &generations[g].steps[s];
IF_DEBUG(gc, debugBelch("update_fwd: %d.%d\n", stp->gen->no, stp->no););
update_fwd(stp->to_blocks);
update_fwd(stp->blocks);
update_fwd_large(stp->scavenged_large_objects);
if (g == RtsFlags.GcFlags.generations-1 && stp->blocks != NULL) {
if (g == RtsFlags.GcFlags.generations-1 && stp->old_blocks != NULL) {
IF_DEBUG(gc, debugBelch("update_fwd: %d.%d (compact)\n", stp->gen->no, stp->no););
update_fwd_compact(stp->blocks);
update_fwd_compact(stp->old_blocks);
}
}
}
// 3. update backward ptrs
stp = &oldest_gen->steps[0];
if (stp->blocks != NULL) {
if (stp->old_blocks != NULL) {
blocks = update_bkwd_compact(stp);
IF_DEBUG(gc, debugBelch("update_bkwd: %d.%d (compact, old: %d blocks, now %d blocks)\n",
stp->gen->no, stp->no,
stp->n_blocks, blocks););
stp->n_blocks = blocks;
stp->n_old_blocks, blocks););
stp->n_old_blocks = blocks;
}
}
......@@ -91,6 +91,7 @@ static TICK_TYPE ExitElapsedTime = 0;
static ullong GC_tot_alloc = 0;
static ullong GC_tot_copied = 0;
static ullong GC_tot_scavd_copied = 0;
static TICK_TYPE GC_start_time = 0, GC_tot_time = 0; /* User GC Time */
static TICK_TYPE GCe_start_time = 0, GCe_tot_time = 0; /* Elapsed GC time */
......@@ -449,7 +450,7 @@ stat_startGC(void)
-------------------------------------------------------------------------- */
void
stat_endGC(lnat alloc, lnat collect, lnat live, lnat copied, lnat gen)
stat_endGC(lnat alloc, lnat collect, lnat live, lnat copied, lnat scavd_copied, lnat gen)
{
TICK_TYPE user, elapsed;
......@@ -483,6 +484,7 @@ stat_endGC(lnat alloc, lnat collect, lnat live, lnat copied, lnat gen)
GC_coll_times[gen] += gc_time;
GC_tot_copied += (ullong) copied;
GC_tot_scavd_copied += (ullong) scavd_copied;
GC_tot_alloc += (ullong) alloc;
GC_tot_time += gc_time;
GCe_tot_time += gc_etime;
......@@ -666,8 +668,12 @@ stat_exit(int alloc)
ullong_format_string(GC_tot_copied*sizeof(W_),
temp, rtsTrue/*commas*/);
statsPrintf("%11s bytes copied during GC\n", temp);
statsPrintf("%11s bytes copied during GC (scavenged)\n", temp);
ullong_format_string(GC_tot_scavd_copied*sizeof(W_),
temp, rtsTrue/*commas*/);
statsPrintf("%11s bytes copied during GC (not scavenged)\n", temp);
if ( ResidencySamples > 0 ) {
ullong_format_string(MaxResidency*sizeof(W_),
temp, rtsTrue/*commas*/);
......@@ -791,11 +797,7 @@ statDescribeGens(void)
for (bd = step->large_objects, lge = 0; bd; bd = bd->link)
lge++;
live = 0;
if (RtsFlags.GcFlags.generations == 1) {
bd = step->to_blocks;
} else {
bd = step->blocks;
}
bd = step->blocks;
for (; bd; bd = bd->link) {
live += (bd->free - bd->start) * sizeof(W_);
}
......
......@@ -71,13 +71,16 @@ initStep (step *stp, int g, int s)
{
stp->no = s;
stp->blocks = NULL;
stp->n_to_blocks = 0;
stp->n_blocks = 0;
stp->old_blocks = NULL;
stp->n_old_blocks = 0;
stp->gen = &generations[g];
stp->gen_no = g;
stp->hp = NULL;
stp->hpLim = NULL;
stp->hp_bd = NULL;
stp->scavd_hp = NULL;
stp->scavd_hpLim = NULL;
stp->scan = NULL;
stp->scan_bd = NULL;
stp->large_objects = NULL;
......@@ -427,8 +430,8 @@ allocNurseries( void )
allocNursery(&nurseries[i], NULL,
RtsFlags.GcFlags.minAllocAreaSize);
nurseries[i].n_blocks = RtsFlags.GcFlags.minAllocAreaSize;
nurseries[i].to_blocks = NULL;
nurseries[i].n_to_blocks = 0;
nurseries[i].old_blocks = NULL;
nurseries[i].n_old_blocks = 0;
/* hp, hpLim, hp_bd, to_space etc. aren't used in the nursery */
}
assignNurseriesToCapabilities();
......@@ -872,7 +875,7 @@ calcLive(void)
step *stp;
if (RtsFlags.GcFlags.generations == 1) {
live = (g0s0->n_to_blocks - 1) * BLOCK_SIZE_W +
live = (g0s0->n_blocks - 1) * BLOCK_SIZE_W +
((lnat)g0s0->hp_bd->free - (lnat)g0s0->hp_bd->start) / sizeof(W_);
return live;
}
......@@ -891,6 +894,9 @@ calcLive(void)
live += ((lnat)stp->hp_bd->free - (lnat)stp->hp_bd->start)
/ sizeof(W_);
}
if (stp->scavd_hp != NULL) {
live -= (P_)(BLOCK_ROUND_UP(stp->scavd_hp)) - stp->scavd_hp;
}
}
}
return live;
......@@ -985,7 +991,7 @@ memInventory(void)
if (RtsFlags.GcFlags.generations == 1) {
/* two-space collector has a to-space too :-) */
total_blocks += g0s0->n_to_blocks;
total_blocks += g0s0->n_old_blocks;
}
/* any blocks held by allocate() */
......@@ -1033,7 +1039,7 @@ checkSanity( void )
nat g, s;
if (RtsFlags.GcFlags.generations == 1) {
checkHeap(g0s0->to_blocks);
checkHeap(g0s0->blocks);
checkChain(g0s0->large_objects);
} else {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment