Re: Bitwise mark-region collection

"Boehm, Hans" <[email protected]> Mon, 10 Jan 2011 20:04:56 +0000
Newsgroups gmane.comp.programming.garbage-collection.general
Message-ID <238A96A773B3934685A7269CC8A8D0426F288571F4@GVW0436EXB.americas.hpqcorp.net>
> From: Jon Harrop
> Hi Hans,
>=20
> Apologies for the fresh post but I read your e-mail before I left and
> no longer have access to it.
>=20
> You mentioned free lists as an alternative. That is actually exactly
> what my last prototype was doing. My free lists were stacks pointed to
> by the first word in the region. Allocation popped a free reference off
> the top of the stack. Freeing pushed an unreachable reference onto the
> stack. With that technique, sweeping was the slowest GC phase and it
> took around 30% of the total running time. With the bitwise technique,
> sweeping is 700x faster according to my benchmarks.
>=20
> I identified several problems with my use of free lists:
I don't think any of these apply to the way we use them.  Sweeping is relat=
ively
cheap for us, and much of the overhead should be cache misses for blocks th=
e client is
likely to write soon anyway.  (At least that's the theory.  I haven't had a=
 chance
to measure.)  Things seem to depend on the context:

>=20
> 1. Disorder accumulates in the stack-based free list unless allocation-
> deallocation happens to be done in FIFO order so there is no locality
> of reference from one allocated block to the next, degrading mutator
> efficiency.
We reconstruct free-lists at GC time, and they're built in address order.
The trade-off is really between scanning the mark bits all at once (good)
and having to build an intermediate data structure (the free-lists, bad).
It's not clear to me that either alternative universally wins.

>=20
> 2. There is no way to exploit the sparsity of deallocations, which
> often occur in contiguous runs when locality is preserved by using an
> allocator that hands out free blocks in order.
If the GC is responsible for most deallocations, then we preserve locality,
and we sometimes do benefit from large empty blocks.

>=20
> 3. The size of the free list is considerable when your allocated blocks
> are as fine-grained as mine (e.g. 50% overhead when allocating 8-byte
> blocks).
We link the blocks themselves through the first word, so there is no space
overhead.

Hans

>=20
> I gave more precise statistics about sparsity in this blog post:
>=20
>   http://flyingfrogblog.blogspot.com/2011/01/importance-of-locality-
> and-sparsity-in.html
>=20
> Note that those results show a value being deallocated as part of a run
> of 23 consecutively-allocated values is 4x more likely that it being
> deallocated alone. I believe this is quite common in functional code
> and is one of the reasons why generational collectors have done so well
> there.
>=20
> My initial thought was, of course, to use a more sophisticated data
> structure to represent the free list in order to combat these
> deficiencies. For example, replacing the stack with an interval tree.
> Then I realised that the size of the free list is so small that a
> bitvector representation would fit into a cache line and allow the core
> operations to be performed on bytes or even whole words at a time
> (replacing 64 64-bit stack pops with a single bitwise int64 AND!)
> whilst simultaneously providing the optimal locality of subsequent
> allocation.
>=20
> So this bitwise approach is my evolution beyond the free list and,
> according to my results, it is a *lot* more efficient.
>=20
> Your point about cache associativity was a very good one that I had
> overlooked. However, most of the time most of the threads will be
> manipulating their own thread-local region's bitvectors so there will
> be no clash and, in a global collection of all regions, far more time
> will be spent marking that rewriting these bitvectors. Loading the two
> bitvectors from two cache lines in a region is sweeping 512 heap blocks
> whereas marking 512 heap blocks is likely to incur >>2 cache misses.
>=20
> If you made any other points that I forgot, please remind me.
>=20
> Cheers,
> Jon.
>=20
>=20
> Trayport Limited
> Registered in England at 4th Floor Rose Court, 2 Southwark Bridge Road,
> London SE1 9HS
> Company registration no.2769279.