From: Daniel J. MacDonald
Subject: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <20040106160131.I1507-100000@attu2.cs.washington.edu>
Now that I have everyone's undivided attention...

A couple of weeks ago I got hankering for some old platform-style 2d
action and decided to put my hypothesis about lisp's suitability for game
logic to the test. Anyway using cl-sdl with opengl I've whipped up a
simple 2d animation and physics system that looks suspiciously like its C
ancestors and I've just finished cleaning up all the trash that it leaves
around. (Any consing in tick-called functions quickly leads to
unnacceptable gc behavior). This involved some pretty hideous macros but I
think lisp comes out of the ordeal not feeling too violated, all things
considered. 

However there is one thing that is driving me nuts. I need to use 
glu:look-at from cl-sdl and it requires double-float args. I do everything 
else in single precision and no other gl functions seem to require double 
floats. Furthermore, for some reason even though I'm block compiling and 
everything glu:look-at wont take non-descriptor representations. So my 
problem is getting descriptor representations of double floats that have 
to be acquired from singles _without_ consing. Granted its only 48 bytes 
per call to look-at, but thats still a couple of mb a minute.

Code-wise, its like this (some decls ommitted):

(deftype vec3 () '(vector single-float))


(defun vec3-x (v) (aref v 0)) 
; etc...

(let (cx ...)
   ; (leave cx as descriptor rep instead of declaring)

   ; horrible consing here | !!
   ;                       v 
   (setf cx (-mystery-function- (vec3-x my-vector)) 
         ...)
   (glu:look-at cx cy cz
               .....)
) 
	

In place of mystery-function, coerce and float result in consing. Not sure
what to do, I've tried everything I can think of, but I've only been using
lisp for a couple months total. If only dynamic-extent were
implemented....

Any ideas from the experienced folks out there?

Daniel

From: Alexey Dejneka
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <m31xqcpax1.fsf@comail.ru>
"Daniel J. MacDonald" <·····@cs.washington.edu> writes:

> However there is one thing that is driving me nuts. I need to use 
> glu:look-at from cl-sdl and it requires double-float args. I do everything 
> else in single precision and no other gl functions seem to require double 
> floats. Furthermore, for some reason even though I'm block compiling and 
> everything glu:look-at wont take non-descriptor representations. So my 
> problem is getting descriptor representations of double floats that have 
> to be acquired from singles _without_ consing.

It is impossible in CMUCL. Better try to use non-descriptor
representation.

> Code-wise, its like this (some decls ommitted):
[slightly compressed]
> (deftype vec3 () '(vector single-float))
> (defun vec3-x (v) (aref v 0)) 
> (let (cx ...)
>    (setf cx (-mystery-function- (vec3-x my-vector))
>          ...)
>    (glu:look-at cx cy cz
>                .....)
> ) 

> In place of mystery-function, coerce and float result in consing.

You can declare GLU:LOOK-AT to be inline; but you must put the
declaration before its definition-AT. In this case the compiler can
use non-descriptor representation and no consing is needed.

> If only dynamic-extent were
> implemented....

I have no experience with DYNAMIC-EXTENT; how are you sure that
LOOK-AT, COERCE and SETQ perform no bookkeeping?

-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer
From: Thomas F. Burdick
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <xcv1xqbmnc1.fsf@famine.OCF.Berkeley.EDU>
"Daniel J. MacDonald" <·····@cs.washington.edu> writes:

> However there is one thing that is driving me nuts. I need to use 
> glu:look-at from cl-sdl and it requires double-float args. I do everything 
> else in single precision and no other gl functions seem to require double 
> floats. Furthermore, for some reason even though I'm block compiling and 
> everything glu:look-at wont take non-descriptor representations.

Is it callable from outside the compilation block?  If so, it has to
take boxed arguments.

> So my problem is getting descriptor representations of double floats
> that have to be acquired from singles _without_ consing. Granted its
> only 48 bytes per call to look-at, but thats still a couple of mb a
> minute.

A double-float plus type tags is too wide, so it necesarily requires
consing.  You're right that dynamic-extent could help you here
somewhat, causing the consing to be done on the stack.  I'd suggest
that you either get the call to glu:look-at inlined, or you spin its
body off into a glu:%look-at function that isn't callable from outside
the compilation block, and call that.  In that case, the Python should
be able to arrange for its arguments to be passed unboxed.


-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Matthew Danish
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <20040107222251.GD31217@mapcar.org>
On Tue, Jan 06, 2004 at 04:36:29PM -0800, Daniel J. MacDonald wrote:
> (deftype vec3 () '(vector single-float))
> 
> 
> (defun vec3-x (v) (aref v 0)) 
> ; etc...
> 
> (let (cx ...)
>    ; (leave cx as descriptor rep instead of declaring)
> 
>    ; horrible consing here | !!
>    ;                       v 
>    (setf cx (-mystery-function- (vec3-x my-vector)) 
>          ...)
>    (glu:look-at cx cy cz
>                .....)
> ) 
> 	

Can you modify mystery-function to take a double-float vector as an
argument, and then have it put the results into the vector directly?
This may not help the glu:look-at call, though, which I suppose will
have to be inlined.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Daniel J. MacDonald
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <20040107215250.M23014-100000@attu4.cs.washington.edu>
Re. this and others' posts:


> >    (setf cx (-mystery-function- (vec3-x my-vector)) 
> >          ...)
> >    (glu:look-at cx cy cz
> >                .....)
> 
> Can you modify mystery-function to take a double-float vector as an
> argument, and then have it put the results into the vector directly?
> This may not help the glu:look-at call, though, which I suppose will
> have to be inlined.
> 

glu:look-at is a foreign routine and calls gluLookAt in opengl's libs, so 
its not clear to me how I could inline it or what that would accomplish. 
I am reluctant to mess with cl-sdl, and I cant see how its entry for 
glu:look-at is different from all the other gl: functions that want single 
floats but dont seem to have this problem.

I did try placing the coerced double floats into some other memory, but I
dont know how to obtain descriptors that point to that memory to give to
glu:look-at. python seems to want to cons whenever I try to pass the
non-descriptor representations. I also dont know how to overwrite the data
portion of a suitable existing descriptor representation without consing a
new one, but this seems like such an obvious thing to want to do... 

Daniel
From: Raymond Toy
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <4nwu82lczy.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Daniel" == Daniel J MacDonald <·····@cs.washington.edu> writes:

    Daniel> Re. this and others' posts:


    >> >    (setf cx (-mystery-function- (vec3-x my-vector)) 
    >> >          ...)
    >> >    (glu:look-at cx cy cz
    >> >                .....)
    >> 
    >> Can you modify mystery-function to take a double-float vector as an
    >> argument, and then have it put the results into the vector directly?
    >> This may not help the glu:look-at call, though, which I suppose will
    >> have to be inlined.
    >> 

    Daniel> glu:look-at is a foreign routine and calls gluLookAt in opengl's libs, so 
    Daniel> its not clear to me how I could inline it or what that would accomplish. 
    Daniel> I am reluctant to mess with cl-sdl, and I cant see how its entry for 
    Daniel> glu:look-at is different from all the other gl: functions that want single 
    Daniel> floats but dont seem to have this problem.

I don't think there should be any consing when calling glu:look-at,
provided glu:look-at is properly defined.  If glu:look-at is truly the
foreign function and not a wrapper, then glu:look-at should still be
declared inline.  This allows the compiler to inline some foreign
function interface code, but the foreign function itself, of course,
isn't.

It might be useful to do a few simple experiments with your own 3-arg
double-float function to see how things work.

    Daniel> I did try placing the coerced double floats into some other memory, but I
    Daniel> dont know how to obtain descriptors that point to that memory to give to
    Daniel> glu:look-at. python seems to want to cons whenever I try to pass the

kernel::get-lisp-obj-address will return the address of the object.
But this probably won't help you since it seems glu:look-at wants a
double-float, not a pointer to a double-float.

Ray
From: Matthew Danish
Subject: Re: gc-less game engine w/ cmucl :)
Date: 
Message-ID: <20040109035203.GE31217@mapcar.org>
On Wed, Jan 07, 2004 at 10:03:47PM -0800, Daniel J. MacDonald wrote:
> glu:look-at is a foreign routine and calls gluLookAt in opengl's libs, so 
> its not clear to me how I could inline it or what that would accomplish. 
> I am reluctant to mess with cl-sdl, and I cant see how its entry for 
> glu:look-at is different from all the other gl: functions that want single 
> floats but dont seem to have this problem.

Raymond has pointed out why you want might want to declare the foreign
function definition inline, and I have successfully done so in other
cases to reduce consing.  Go ahead and put an inline declaration in the
file before the definition, it's perfectly alright to try.  The only
reason why I didn't do so was that I never noticed a problem before.  I
have wondered before whether it was safe to inline every foreign
function, but I do not remember why I did not.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."