Skip to content

Instantly share code, notes, and snippets.

@axman6
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save axman6/46edae58cc4e8242bdac to your computer and use it in GitHub Desktop.
Save axman6/46edae58cc4e8242bdac to your computer and use it in GitHub Desktop.
GHC scavenge_large_srt_bitmap possible optimisation
/* Similar to scavenge_large_bitmap(), but we don't write back the
* pointers we get back from evacuate().
*/
#define SPARSE_BITS 8
static void
scavenge_large_srt_bitmap( StgLargeSRT *large_srt )
{
nat i, j, size;
StgWord bitmap;
StgClosure **p;
size = (nat)large_srt->l.size;
p = (StgClosure **)large_srt->srt;
// Iterate
for (i = 0; i < (size + BITS_IN(_W) - 1) / BITS_IN(W_); i++) {
bitmap = large_srt->l.bitmap[i];
if (bitmap == 0){
p += BITS_IN(W_);
} else {
// If everything needs evacuating, go for it
if (bitmap == (StgWord)(-1))
{
#pragma unroll
for (int i = 0; i < BITS_IN(W_); ++i, ++p)
{
evacuate(p);
}
} // Slow O(BITS_IN(W_)) algorithm, probably faster for dense bitmaps
else if (hs_popcnt(bitmap) > SPARSE_BITS) {
for (j = 0; j < BITS_IN(W_); j++) {
if ((bitmap & 1) != 0) {
evacuate(p);
}
p++;
bitmap = bitmap >> 1;
}
}
else { // If there are few bits set, several iterations and branches can be saved
// by jumping to each set bit
do {
#if SIZEOF_HSWORD == 4
StgWord bpos = hs_ctz32(bitmap);
#else
StgWord bpos = hs_ctz64(bitmap);
#endif
p += bpos;
evacuate(p);
bitmap = bitmap >> bpos;
} while (bitmap != 0);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment