[plt-scheme] More PLT Scheme as an Alternative to Matlab

From: Eli Barzilay (eli at barzilay.org)
Date: Thu Aug 13 22:59:09 EDT 2009

On Aug 13, Doug Williams wrote:
> 
> For the PLT implementors. I'm using SRFI 4 as the underlying
> representation for storing the arrays. They store the data in the
> formats we want, but don't seem to be processed efficiently.
> Although efficiency isn't a real concern at this stage, it will be
> for some people at some point. Any idea of what we can do better is
> more than welcome.

The srfi-4 representation can be more efficient in some cases, and
less in other cases...  The basic idea is that the vector is saved
directly as the C vector, so memory is more efficient than plain
Scheme values.  For example, a floating point number in Scheme is
(usually) a boxed object, so the machine representation is a pointer
to the value.  Here's a quick list of things that are relevant.

* If you're dealing with external code a lot (for example, and
  interface to some algebra library), then you save a lot of
  translation overhead since the data is (usually) in a format that
  the external library can use as is.

* However, if you're doing a lot of work *inside* Scheme, then things
  can become very inefficient.  For example, say that you want to loop
  over a floating point array and multiply all of the values by a
  given factor.  What will happen in this case is: each time you read
  a value, you allocate a Scheme object for the fp number, multiplying
  that allocates a new one, then saving it copies the result back to
  the array, leaving the two allocated values to be GCed.  (There are
  some JIT-level optimizations for fp numbers, I don't know if it can
  save one of these allocations in this case.)

  So the bottom line is: using the srfi-4 representation can work well
  if you usually operate on the data as an opaque blob of values, and
  only get back the Scheme values at the end.

* Another issue here is with mutation -- if the external call changes
  values, then the changes will be visible on the Scheme side with no
  further work.

* However, you should be careful as usual with C code:
  - If you deal with a library that can allocate such a vector and
    hand it back to you -- then this memory will not be visible to the
    GC and will need an explicit `free'.
  - srfi-4 vectors are allocated as usual, which means that the 3m GC
    will move them around.  This can be important if the C code might
    retain a pointer to such a vector -- when a later call to the C
    code is done, the block is likely to be in a different place, with
    the usual C response (segfault in the best case, complete mess in
    the worst case).

* Another point to consider is huge arrays -- if you expect to have
  such arrays, then it might be better to do the allocation explicitly
  outside of the GC -- using `malloc' in 'raw mode.  This will require
  registering finalizers to free them, but the benefits are:
  - You can have a huge array without worrying about the 3m GC that
    usually requires double the space that you're using.
  - Dealing with an external library that allocates an array becomes
    easy, since it's dealt with in the same way.
  - No issues with arrays moving around, for external code that keeps
    pointers to it.  (I can imagine this being a real benefit if there
    are libraries that can use multiple cores and calling a callback
    function when the operation is done.)

* Finally, it sounds like it might be more convenient to use the
  `cvector' representation from the foreign interface: this is very
  similar to the srfi-4 representation, except that the type is stored
  in the cvector rather than having a separate type for each kind of
  vector.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!


Posted on the users mailing list.