[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lisp floating point performance



>> The abysmal performance of virtually all current Lisp implementations
>> on floating point is indeed awful.  

With the proper declaration of variables and functions, floating point
performance can be implemented very efficiently.  If you want to see
amazing floating point performance, check out the lucid compiler or
the CmuCommonLisp python compiler.  (Unfortunately, neither of these
implementations work on the Mac.)  These compilers can generate inline
zero-consing floating point instructions for code within a function.
(I talk about float function calls later.)  The technique is to use
very good type propagation and non-descriptor floats (i.e., no tags).
With complete declarations of variables the compiler can safely
generate inline floating point code that manipulates native floating
point data.

There are a couple of caveats.  First, the implementation must provide
a mechanism to store the non-descriptor floating point values back
into the user's data structures without consing.  The two previously
mentioned implementations provide vectors of non-descriptor floats.
Unfortunately, there is no natural way to store a non-descriptor float
back to a defstruct structure without consing (even if the type of the
slot is declared).  I am told this will be fixed in the next version
of Cmu CommonLisp.  If you really want to store a non-descriptor float
in a structure, have the slot contain a non-descriptor float vector of
length one (instead of a float).  The accesses are more involved but
no garbage is created.

The second caveat is that no implementation (on stock hardware) that I
know of provides a way to pass floating values to a function or return
a floating point value from a function without consing.  The work
around is to pass/return values in non-descriptor float vectors.  This
can be done more generally in a somewhat unugly way.  If the user is
willing to guarantee that a function's args and return values will not
change between recompiles then the compiler can rely on an ftype
declaration and generate code that passes/returns floats on the
stack/registers.  This assumption is not entirely unreasonable; it is
very similar to the defstruct (no) redefinition assumption (see page
473 of CLtL II).  This would be an incredible win for floating point
consumers, since even now in the Lucid implementation, calling
CommonLisp predefined float functions conses.  These two Lisp's will
get rid of the consing if the function is inlined, but this won't work
for generic functions (and lucid won't allow predefines to be
inlined).

In conclusion, Cmu and Lucid CommonLisp both provide very efficient
floating point performance, much much more efficient than MCL.  I too
have written a neural network simulator, but I wrote it using Lucid
4.0 on the SparcStation (or decStation 5000 or Sun3) and the
performance is sometimes even better than comparable C code!  Of
course because of the aforementioned caveats I had to be careful about
function calls and structure references, but there are manageable
workarounds.

I strongly encourage the implementors of MCL to provide:

(1) both single and double float data types
(2) non-descriptor float vectors (maybe this already exists)
(3) non-descriptor structure floats 
(4) ability to inline properly defined floating point calculation
    within a function using non-descriptor floats.
(5) ability to use ftype declarations to produce zero-consing calling
    and returning from float functions.

There is no need to resort to Erann Gat's "Floating Point Compiler for
Macintosh Common Lisp, version 1.2a1".  Although, I definitely
appreciate his effort (thank you Erann!), MCL can be improved to
accomodate our wishes.

-- jonathan bachrach (bachrach@psych.stanford.edu)