From: bradb
Subject: Preventing GC stalls
Date: 
Message-ID: <1127534060.981935.183380@g14g2000cwa.googlegroups.com>
Hi all, I have been playing with CMUCL Lisp for a few days now.
Because I am interested in OpenGL, I've started with the CL ports of
Nehe's tutorials, namely tutorial 5.  This tutorial features a spinning
cube and a spinning pyramid.  The data structures are simple lists & I
noticed that when I run the app the frame rate stalls periodically -
when the garbage is collected.  Basically I would like to stop this
stalling behaviour.  Initially I thought that if I could stop the
functions from consing then the GC would not need to collect.  However,
even this simple program conses 40 bytes per call.
(defun nothing (l))
(dotimes (x 10000)
 (nothing x))

Soooo, even this collects garbage.  How does one go about writing a
program that doesn't collect?  I want to be able to write a game loop
that basically is memory efficient during the level, because big pauses
in an interactive game is bad.

Thanks
Brad

From: Steven M. Haflich
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <4334CFBF.3030802@alum.mit.edu>
bradb wrote:

> Soooo, even this collects garbage.  How does one go about writing a
> program that doesn't collect?  I want to be able to write a game loop
> that basically is memory efficient during the level, because big pauses
> in an interactive game is bad.

Try compiling your code.

However, it is in the nature of Lisp code to cons.  If you restrict
yourself to writing only code that doesn't cons, then you lose many
of the significant benefits of Lisp.

It is possible to write a Lisp system that does gc either in parallel
(on a mp machine) or in arbitrarily small increments even on a single
processor machine.  The problem with such implementations (at least
on stock hardware) is that they run some degree slower than the
usual stop-and-gc systems, so not everyone wants to pay the price.
They also cost a good deal of expensive technical time to develop
and make perfectly robust.
From: bradb
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <1127543302.430227.223130@o13g2000cwo.googlegroups.com>
Ah, compiling my code fixed it.  I realise that I need not really worry
about Lisp consing - but I figure that I should find out if it is
possible to write "smooth" code.  Because if I couldn't do that then I
ought to not bother with Lisp as it wouldn't suit my needs.

Thanks
Brad
From: Christopher C. Stacy
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <ubr2jys1e.fsf@news.dtpq.com>
"bradb" <··············@gmail.com> writes:

> Hi all, I have been playing with CMUCL Lisp for a few days now.

> even this simple program conses 40 bytes per call.
> (defun nothing (l))
>   (dotimes (x 10000)
>     (nothing x))

The problem must be in your function NOTHING,
because the rest of the program does not cons.
(At least, not in SBCL, interpreted or compiled.)
From: bradb
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <1127543745.235340.50350@g14g2000cwa.googlegroups.com>
The function nothing is just nothing,
(defun nothing (l))

I just got the latest SBCL, and ran the same thing with profiling - it
still reports about 500,000 consed bytes.  That could be profiler
overhead though.

Brad
From: Thomas F. Burdick
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <xcvek7ei356.fsf@conquest.OCF.Berkeley.EDU>
······@news.dtpq.com (Christopher C. Stacy) writes:

> The problem must be in your function NOTHING,
> because the rest of the program does not cons.
> (At least, not in SBCL, interpreted or compiled.)

And how exactly did you get SBCL to interpret it?  Being as how it
doesn't have an interpreter[*] that's quite a feat.  I suspect that
you just entered it at the repl, though, in which case it's compiled.

[*] There is one in on a branch in CVS, but not in any released sbcl.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Christopher C. Stacy
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <u7jd6yt5n.fsf@news.dtpq.com>
···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> ······@news.dtpq.com (Christopher C. Stacy) writes:
> 
> > The problem must be in your function NOTHING,
> > because the rest of the program does not cons.
> > (At least, not in SBCL, interpreted or compiled.)
> 
> And how exactly did you get SBCL to interpret it?  Being as how it
> doesn't have an interpreter[*] that's quite a feat.  I suspect that
> you just entered it at the repl, though, in which case it's compiled.

Aha!  Well, that explains some things...
From: Thomas F. Burdick
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <xcv64spipj7.fsf@conquest.OCF.Berkeley.EDU>
······@news.dtpq.com (Christopher C. Stacy) writes:

> ···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> 
> > ······@news.dtpq.com (Christopher C. Stacy) writes:
> > 
> > > The problem must be in your function NOTHING,
> > > because the rest of the program does not cons.
> > > (At least, not in SBCL, interpreted or compiled.)
> > 
> > And how exactly did you get SBCL to interpret it?  Being as how it
> > doesn't have an interpreter[*] that's quite a feat.  I suspect that
> > you just entered it at the repl, though, in which case it's compiled.
> 
> Aha!  Well, that explains some things...

Not least the compiler warnings and notes you can get when typing
things at the repl :-)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Julian Squires
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <TLSdnRgGWOr936jeRVn-gA@rogers.com>
On 2005-09-24, bradb <··············@gmail.com> wrote:
> Hi all, I have been playing with CMUCL Lisp for a few days now.
> Because I am interested in OpenGL, I've started with the CL ports of
> Nehe's tutorials, namely tutorial 5.  This tutorial features a spinning
> cube and a spinning pyramid.  The data structures are simple lists & I
> noticed that when I run the app the frame rate stalls periodically -
> when the garbage is collected.  Basically I would like to stop this
> stalling behaviour.  Initially I thought that if I could stop the
> functions from consing then the GC would not need to collect.  However,
> even this simple program conses 40 bytes per call.

Beware CL-SDL and so on in term of consing... this is something that may
get fixed if they move to CFFI, but I found them totally unusable,
consing-wise, for real game purposes, and ended up writing my own
bindings (with more of the library level stuff wrapped in C, plus a
redefinition of with-foreign-objects to better accomidate the cmucl/sbcl
ffi).

Basically the problem is that UFFI on CMUCL or SBCL won't allow enough
information down to the native FFI, and things which should get stack
allocated end up having to be heap allocated, leading to a lot of
unnecessary consing.

> Soooo, even this collects garbage.  How does one go about writing a
> program that doesn't collect?  I want to be able to write a game loop
> that basically is memory efficient during the level, because big pauses
> in an interactive game is bad.

I think the right approach in a gaming context is twofold -- minimize
consing as much as possible, and disable GC during the main game loop.
If you have a level-oriented game, you can get away with just doing your
GC at the end of each level.  If not, you may find it useful to insert
GC checkpoints at opportune points in your game world.

The ideal thing would be to have GC that doesn't have to interrupt the
graphics thread, but I haven't figured out how to do that in a useful
way.  I am still a novice as far as GC implementations go.

Another alternative is to use CL as a development language, and create a
less-dynamic subset with manual memory operations for deployment
purposes.  Some assembly required. ;-)

Cheers.

-- 
Julian Squires
From: bradb
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <1127579388.832334.5340@g49g2000cwa.googlegroups.com>
Thanks for that good info Julian.  I think that I will keep playing
with CL until I know it a little better & then make a decision on how
much this is going to bother me.

Brad
From: Rob Thorpe
Subject: Re: Preventing GC stalls
Date: 
Message-ID: <1127663457.379169.108510@o13g2000cwo.googlegroups.com>
bradb wrote:
> Thanks for that good info Julian.  I think that I will keep playing
> with CL until I know it a little better & then make a decision on how
> much this is going to bother me.

Controlling the GC programmatically can help, both when it happens and
after how much consing.