
On 02/03/10 20:37, Luke Palmer wrote:
On Tue, Mar 2, 2010 at 7:17 AM, Simon Marlow
wrote: For games, though, we have a very good point that occurs regularly where we know that all/most short-lived objects will no longer be referenced - at the start of a fresh frame.
System.Mem.performGC is your friend, but if you're unlucky it might do a major GC and then you'll get more pause than you bargained for.
Some fine-grained control might be nice here. Eg. I could do a major GC as a player is opening a menu, on a loading screen, when the game is paused, or some other key points, and it might still be annoying, but at least it wouldn't interfere with gameplay. There is of course the question of what happens if one of these key points doesn't happen when we need to do an allocation, but... oh well. Perhaps that could be mitigated by saying "I would rather you allocate than major GC right now". Are any of these options impossible, or be unreasonably difficult to implement (I don't suspect so)?
Actually that's one thing we can do relatively easily, i.e. defer major GC for a while. Due to the way GHC has a two-layer memory manager, the heap is a list of discontiguous blocks, so we can always allocate some more memory. So it would be pretty easy to provide something like disableMajorGC, enableMajorGC :: IO () Of course leaving it disabled too long could be bad, but that's your responsibility. Oh, I just checked and System.Mem.performGC actually performs a major GC, here's its implementation: foreign import ccall {-safe-} "performMajorGC" performGC :: IO () to perform a minor GC (or possibly a major GC if one is due), you want this: foreign import ccall {-safe-} "performGC" performMinorGC :: IO () Cheers, Simon