On 25 May 2013 00:58, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
On Fri, May 24, 2013 at 09:34:41AM +1000, Manu wrote:
[...]
> Just to be clear, while I've hard many have, I've NEVER argued for
> removing the GC. I think that's a hallmark of a modern language. I
> want to use the GC in games, but it needs to have performance
> characteristics that are applicable to realtime and embedded use.
> Those are:
> 1. Can't stop the world.
> 2. Needs tight controls, enable/disable, and the allocators interface
> so alternative memory sources can be used in mane places.
> 3. Needs to (somehow) run incrementally. I'm happy to budget a few
> hundred 盜 per frame, but not a millisecond every 10 frames, or 1
> second every 1000.
>     It can have 1-2% of overall frame time each frame, but it can't
> have 10-100% of random frames here and there. This results in
> framerate spikes.

Makes sense, so basically the GC should not cause jittery framerates,
but should distribute its workload across frames so that the framerate
is more-or-less constant?

Precisely.

> The GC its self can be much less efficient than the existing GC if it
> want's, it's only important that it can be halted at fine grained
> intervals, and that it will eventually complete its collect cycle over
> the long-term.
>
> I know that an incremental GC like this is very complex, but I've
> never heard of any real experiments, so maybe it's not impossible?

Is there a hard upper limit to how much time the GC can take per frame?
Is it acceptable to use, say, a millisecond every frame as long as it's
*every* frame and not every 10 frames (which causes jitter)?

Errr, well, 1ms is about 7% of the frame, that's quite a long time.
I'd be feeling pretty uneasy about any library that claimed to want 7% of the whole game time, and didn't offer any visual/gameplay benefits...
Maybe if the GC happened to render some sweet water effects, or perform some awesome cloth physics or something while it was at it ;)
I'd say 7% is too much for many developers.

I think 2% sacrifice for simplifying memory management would probably get through without much argument.
That's ~300µs... a few hundred microseconds seems reasonable. Maybe a little more if targeting 30fps.
If it stuck to that strictly, I'd possibly even grant it permission to stop the world...

For me, I'm also interested in incremental GCs -- for time-sensitive
applications (even if it's just soft realtime, not hard), long
stop-the-world pauses are really disruptive. I'd rather have the option
of a somewhat larger memory footprint and a less efficient GC (in terms
of rate of memory reclamation) if it can be incremental, rather than a
very efficient GC that introduces big pauses every now and then. I'm
even willing to settle for lower framerates if it means I don't have to
deal with framerate spikes that makes the result jittery and unpleasant.

One important detail to consider for realtime usage, is that it's very unconventional to allocate at runtime at all...
Perhaps a couple of short lived temp buffers each frame, and the occasional change in resources as you progress through a world (which are probably not allocated in GC memory anyway).
Surely the relatively high temporal consistency of the heap across cycles can be leveraged here somehow to help?