> At 6:16 PM -0400 8/20/02, John Porter wrote:
> >Dan Sugalski wrote:
> >>  I expect a UINTVAL should be sufficient to hold the counter.
> >
> >Why?  Because you don't expect a perl process to run longer
> >than a couple hours?  Or because rollover won't matter?
>
> Rollover won't really matter much, if we're careful with how we
> document things. Still, a UINTVAL should be at least 2^32--do you
> really think we'll have that many GC generations in a few hours?

Currently, 5000 iterations of life execute in 6 seconds, with 42K DOD
runs. At that rate, we have a rollover every week. Not really a problem,
but if we have code which doesn't allow for rollover, it is a problem.

I can see using the generations value to handle code that is dependant
upon things "changing". However, as Steve mentioned, it's probably
easiest and fastest to just always re-dereference the bufstart.

It might be useful to specify the generation within a pool, with the
assumption that the GC would track it and promote it to a different
generational pool before an overflow occurs. But it'd make more sense to
use a byte/short for this, and reset it to 0 with each promotion. (Or in
the case of the final generation, ignore rollover.)

A dod generation count doesn't buy us much. Because we don't track
inter-pool pointers, we need to do a full dod every time we need to
determine the root set. However, copy collection can be localized to a
given pool, and as long as we copy every header into that pool, we can
avoid copying a lot of data.

If we have more DOD's than collections, it would make sense to just
iterate over the header list with each collection to search for pool
pointers, and hope the generational overhead is outweighed by the ability
to avoid re-copying stuff. This will probably be more apparent with
real-world programs than test programs that can keep every bit of memory
in the cache.

If collections are more frequent than DODs, we might be able to  set up
lists of pointers on a DOD run, organized into generational pool, and just
use those during collection. That's effectively one additional pointer per
header, however. And there are better uses for such space.

Finally, it's possibly to do whole-scale generational promotion of an
entire pool, and avoid a generations count altogether. I forget the
details exactly, but it involves seperating each generation into two
pools, and storing the generation count in the pool itself. It introduces
some error into the promotion rates (some stuff is promoted too early,
some too late), but it avoids the extra generational count.


So in conclusion, generational systems can be done using at most a byte or
a short, and it's even possible to do them with nothing at all. So until
the need arises, I don't think the generations count would be worth it.
Especially since I plan to try and prove the need for a header pool
pointer at some point. :)

Mike Lambert



Reply via email to