List Info

Thread: Re: alien use causes gratuitous GC




Re: alien use causes gratuitous GC
user name
2007-12-22 02:21:54
--- Raymond Toy <toy.raymondgmail.com> wrote:
> If it's not too large, could you just send the Lisp
callback
routines?  
> That should give some hints on what's happening even if
we don't have
> the foreign libraries.

I'll send what's manageable. I forgot one level of callback.
 
It's actually: Lisp -> C -> Lisp -> C if you can
believe it.

Here are the relevant alien definitions.

;; These are C functions called from the Lisp system of
equations
function.
(def-alien-routine get_sysvar_n int)
(def-alien-routine get_sysvar_val double  (i int))
(def-alien-routine get_sysvar_dotval double  (i int))
(def-alien-routine set_sysvar_val void  (i int)  (x
double))
(def-alien-routine set_sysvar_dotval void  (i int)  (x
double))

;; these C functions are called once per complete
simulation
(def-alien-routine init_dims void (nsys_var int)  (nparam
int)
  ;; this registers the Lisp callback for the system of
equations
  (model (* (function void (double-float)))))
(def-alien-routine mem_alloc int)
(def-alien-routine mem_free void)
(def-alien-routine fill_in int (start_time double)
  (init_vals (* double-float)) (sa int))
(def-alien-routine init_cvode void (init_vals (*
double-float))
  (start_time double))
(def-alien-routine sim_model_cvode int
  (sample_time double))

The system of equations is built dynamically.  Slightly
edited
code for this is included below and an example function is
given at the end of the email:
(defun cvode-make-MS-model (system sa?)
  `(progn
     ,(append 
        '(def-callback MS_model (void (time c-call:double))

	       (declare (optimize (speed 3) (safety 0))))
;; this adds some general Lisp code
       (assign-exo-vars (getv-exogenous-variables) 'time)
;; this adds Lisp code that calls C functions (see below)
       (cvode-assign-sys-vars)
;; this adds more Lisp code that calls some C functions
       (cvode-generate-f-equations system sa? t))))

;; this builds a part of the equations that calls C from
;; Lisp: get_sysvar_val(i), is a simple function that lets
;; Lisp access an array stored in C. 
(defun cvode-assign-sys-vars ()
  (let ((syslst))
    (dotimes (i (length *system-variables*) syslst)
      (push `(setf (aref *system-variables* ,i) 
		   (get_sysvar_val ,i))
	    syslst))))

;; here's the declaration of get_sysvar_val from above
double get_sysvar_val(int i) {return sys_var.vals[i];}

;; i call this function once for each of n variables for
each 
;; explicit time step passed to the solver.  so, for one
full
;; simulation, this function could be called hundreds of 
;; times.
;; here's a note that I wrote myself regarding Clisp that
might
;; be helpful when thinking about CMUCL:
;;; when clisp calls the function get_sysvar_val, it
allocates 16
;;; bytes of memory in which it stores the return value. 
each call to
;;; get_sysvar_val grabs 16 more bytes, which can add up to
a
;;; substantial amount of memory (and GC calls) during
simulation.
;;; so, we duplicate the values of the system variables
locally (i.e.,
in
;;; Lisp) to speed up access time and to avoid unnecessary
garbage.

Finally, here is an example system of equations generated
during
runtime.

(DEF-CALLBACK MS_MODEL
                  (VOID
                   (TIME
                     DOUBLE))
                  (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)))
                  (SETF (AREF *SYSTEM-VARIABLES* 1)
(GET_SYSVAR_VAL 1))
                  (SETF (AREF *SYSTEM-VARIABLES* 0)
(GET_SYSVAR_VAL 0))
                  (SET_SYSVAR_DOTVAL 1
                                     (EQUATION-AGGREGATOR
                                      #<Function +
>
                                      (* -1.0d0
                                         (THE DOUBLE-FLOAT
                                              (AREF
*MODEL-CONSTANTS*
3))
                                         (THE DOUBLE-FLOAT
                                              (AREF
*SYSTEM-VARIABLES*
1))
                                         (THE DOUBLE-FLOAT
                                              (AREF
*SYSTEM-VARIABLES*
0)))
                                      (*
                                       (THE DOUBLE-FLOAT
                                            (AREF
*MODEL-CONSTANTS* 1))
                                       (THE DOUBLE-FLOAT
                                            (AREF
*SYSTEM-VARIABLES*
1))
                                       (- 1
                                          (*
                                           (THE
DOUBLE-FLOAT
                                                (AREF
*MODEL-CONSTANTS*
0))
                                           (THE
DOUBLE-FLOAT
                                                (AREF
*SYSTEM-VARIABLES*
                                                     
1)))))))
                  (SET_SYSVAR_DOTVAL 0
                                     (EQUATION-AGGREGATOR
                                      #<Function +
>
                                      (*
                                       (THE DOUBLE-FLOAT
                                            (AREF
*MODEL-CONSTANTS* 4))
                                       (THE DOUBLE-FLOAT
                                            (AREF
*MODEL-CONSTANTS* 3))
                                       (THE DOUBLE-FLOAT
                                            (AREF
*SYSTEM-VARIABLES*
1))
                                       (THE DOUBLE-FLOAT
                                            (AREF
*SYSTEM-VARIABLES*
0)))
                                      (* -1.0d0
                                         (THE DOUBLE-FLOAT
                                              (AREF
*MODEL-CONSTANTS*
2))
                                         (THE DOUBLE-FLOAT
                                              (AREF
*SYSTEM-VARIABLES*
0))))))



Re: alien use causes gratuitous GC
user name
2007-12-22 08:41:37
Will wrote:
> Here are the relevant alien definitions.
>
> ;; These are C functions called from the Lisp system of
equations
> function.
> (def-alien-routine get_sysvar_n int)
> (def-alien-routine get_sysvar_val double  (i int))
> (def-alien-routine get_sysvar_dotval double  (i int))
> (def-alien-routine set_sysvar_val void  (i int)  (x
double))
> (def-alien-routine set_sysvar_dotval void  (i int)  (x
double))
>
>   
Alien routines should be declared inline to reduce/eliminate
consing, 
according to the manual.
> ;; this builds a part of the equations that calls C
from
> ;; Lisp: get_sysvar_val(i), is a simple function that
lets
> ;; Lisp access an array stored in C. 
> (defun cvode-assign-sys-vars ()
>   (let ((syslst))
>     (dotimes (i (length *system-variables*) syslst)
>       (push `(setf (aref *system-variables* ,i) 
> 		   (get_sysvar_val ,i))
> 	    syslst))))
>
> ;; here's the declaration of get_sysvar_val from above
> double get_sysvar_val(int i) {return sys_var.vals[i];}
>
>   
You could, if desired, declare the alien structure in Lisp
and access 
them directly.  But the alien interface should work fine
too.
> ;; i call this function once for each of n variables
for each 
> ;; explicit time step passed to the solver.  so, for
one full
> ;; simulation, this function could be called hundreds
of 
> ;; times.
>   
Which function are you talking about?  get_sysvar_val?  If
so, declaring 
inline should help.
> (DEF-CALLBACK MS_MODEL
>                   (VOID
>                    (TIME
>                      DOUBLE))
>                   (DECLARE (OPTIMIZE (SPEED 3) (SAFETY
0)))
>                   (SETF (AREF *SYSTEM-VARIABLES* 1)
(GET_SYSVAR_VAL 1))
>                   (SETF (AREF *SYSTEM-VARIABLES* 0)
(GET_SYSVAR_VAL 0))
>   
Is *system-variables* declared to be an array of
double-floats?  That 
will reduce consing.
>                   (SET_SYSVAR_DOTVAL 1
>                                     
(EQUATION-AGGREGATOR
>   
EQUATION-AGGREGATOR will also cons.  That seems unavoidable
unless you 
make it a local function , inline it, or use block
compilation.

It's not quite clear to me, but is ms_model generated once
and solved?  
Then a new ms_model is generated and solved again for a
different problem?

To reduce consing, I think the defcallback needs to be
compiled too.

That's all I can think of right now, after looking at your
code for a 
few minutes,

Ray



[1-2]

about | contact  Other archives ( Real Estate discussion Medical topics )