[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
floating point performance
The problem of consing floating point values when calling functions
plagues me. For instance, inlining just won't help when you're
dealing with generic functions and in general, code is severely
uglified when trying to get maximal performance. I truly want to be
able to make lisp as fast as C and I think this is possible.
I have a suggestion for making floating point function calls more
efficient. Why can't the compiler rely on ftype declarations and
generate code that passes/returns floats on the stack/registers?
Here is the scenario:
The user declares the type of the function:
(declaim (ftype (function (double-float double-float) double-float) sum+2))
Then, the user declares the function:
(defun sum+2 (x y)
(declare (type double-float x y)
(values double-float))
(+ (+ x y) 2.0))
Finally, the user declares functions that call the float function, sum+2.
(defun sum*2+2 (x y)
(declare (type double-float x y)
(values double-float))
(* 2.0 (sum+2 x y)))
Since the compiler has the ftype information for the function, it can
call sum+2 using floats allocated on the stack and expect a return
value in a register or on the stack.
This scenario relies on the fact that (1) the ftype of sum+2 does not
change and (2) the ftype of sum+2 is defined before a function calling
sum+2 is compiled or evaluated. These restrictions very closely
resemble similar assumptions having to do with defstruct. In fact on
page 473 of CLtL II, GLS writes:
X3J13 voted in January 1989 <56> to specify that the results of
redefining a defstruct structure (that is, evaluating more than one
defstruct structure for the same name) are undefined.
The problem is that if instances have been created under the old
definition then remain accessible after the new definition has been
evaluated, the accessors and other functions for the new definition
may be incompatible with the old instances. Conversely, functions
associated with the old definition may have been declared inline and
compiled into code that remains accessible after the new definition
has been evaluated; such code may be incompatible with the new
instances.
In practice this restriction affects the development and debugging
process rather than production runs of fully developed code. The
defstruct feature is intended to provide "the most efficient"
structure class. CLOS classes defined by defclass allow much more
flexible structures to be defined and redefined.
Programming environments are allowed and encouraged to permit
defstruct redefinition, perhaps with warning messages about possible
interactions with other parts of the programming environment or memory
state. It is beyond the scope of the Common Lisp language standard to
define those interactions except to note that they are not portable.
Obviously, problems will arise if a function call is compiled before
it is defined (with its associated ftype declaration). Possibly a
remedy is to add a declaration extension (i.e., ftype* or freeze) that
emphasizes the dangerousness of this definition (or at least a flag
that tells the compiler whether or not to take advantage of the ftype
information).
Please let me know what you think!
-- jonathan bachrach (bachrach@psych.stanford.edu)