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

*To*: maida@cs.psu.edu (Anthony Maida)*Subject*: Re: Allegro CL Floating Point*From*: John Irwin <jdi@Franz.COM>*Date*: Tue, 5 Dec 89 21:28:04 EST*Cc*: Allegro-CL@ucbvax.Berkeley.EDU*In-reply-to*: Your message of Thu, 30 Nov 89 15:29:37 -0500. <8911302029.AA00853@sol4>

Your message: We need to do fast floating point in Lisp. We have benchmarked a C program and a Lisp program. Both programs call an exponential function and a trig function 250,000 times. The C program runs in under 10 seconds. The Lisp program takes at least 50 seconds. We can't understand why there should be such a discrepancy. Can anyone replicate this and explain the discrepancy? We are using the following version of Allegro 3.1.beta.22 [Sun4] (6/8/89) ... -------- First of all, as someone on this list already pointed out, a smart compiler can totally eliminate the loop in the example you gave, resulting in a artificially low result. Here is a slightly better example: C: #include <math.h> #define cnt 500 main() { int i,j; double b = 0.1; for (i=0; i<cnt; i++) for (j=0; j<cnt; j++) { b = exp(b); b = cos(b); } } CL: (defun speed () (declare (optimize (speed 3) (safety 0))) (let ((b 0.0d0)) (declare (double-float b)) (dotimes (i 500) (dotimes (j 500) (setf b (exp b)) (setf b (cos b)))))) After some experimentation, it turns out the major reason that lisp does not perform in the same magnitude as C here is because Allegro CL uses a machine independent version of the math library. We do this because we want to guarantee getting the same result from the same value on different machines. Also we know that the math library we use works correctly for the boundary cases, whereas Sun's, for example, barfs on some boundary conditions. Also note that I have re-written your example so that both C and Lisp are using double precision floating point numbers. Your previous example had C using double and Lisp using single. Cos() and Exp() both take double precision arguments and return double precision results, so to use these with singles requires two conversions. Unfortunately our implementation of this is not optimal in the current product. However, after some experimentation we have found a way to improve this double conversion greatly. I have added this RFE to our RFE list and it should appear in a future release of Allegro CL. In the mean time, if you really need to use single floats rather than double floats, I suggest converting them at the beginning and end of the speed-dependent code, and using doubles inside that code. Now, on to solving your problem. Since the slowness is in our math library, if you can use Sun's library you'll get a large speedup. Of course, you have to guarantee not to pass bad arguments, since these routines are not as safe as our routines. Allegro CL 3.1 final (which you should receive in a few weeks) has a special direct calling foreign function system for the sun4. This allows a much faster than normal call to foreign code. (Note that the below example will work in 3.1.beta.28, but you won't get the numbers I get since the fast foreign function code was done between 3.1.beta.28 and 3.1.) Here is the above example rewritten to use this fast foreign function hook to call into Sun's math library. (Note that this code is rather ugly) ;; These get rid of duplicate symbols already in the Lisp. (remove-entry-point "_exp") (remove-entry-point "_cos") (remove-entry-point "_sin") (remove-entry-point "_tan") (remove-entry-point "_sincos") ;; This loads in Sun's implementations of exp() and cos(). (load "" :unreferenced-lib-names '("_exp" "_cos") :system-libraries '("m")) (defforeign 'c-exp :entry-point "_exp" :arguments '(double-float) :arg-checking nil :call-direct t :callback nil :allow-other-keys t :return-type :double-float) (defforeign 'c-cos :entry-point "_cos" :arguments '(double-float) :arg-checking nil :call-direct t :callback nil :allow-other-keys t :return-type :double-float) (defun speed () (declare (optimize (speed 3) (safety 0))) (let ((b 0.0d0)) (declare (double-float b)) (dotimes (i 500) (dotimes (j 500) (setf b (c-exp b)) (setf b (c-cos b)))))) Here are the numbers I get for the above examples on a 4/260 with Allegro CL 3.1.4. Units are user time, Lisp times include gc time. PRECISION C STD LISP LISP WITH FAST SUN MATH double 11 48 20 In addition, we plan to further improve the fast foreign function calling mechanism, which should speed up this last example considerably, probably to the point where it is equivalent to C. We hope to make this improvement available as a patch to 3.1, otherwise it will be available in a future release. If you have any questions or feel this approach will not solve your problem please contact us for assistance. -- John Irwin Franz Inc.

**References**:**Allegro CL Floating Point***From:*maida@cs.psu.edu (Anthony Maida)

- Prev by Date:
**Re: multiprocessing scheduling** - Next by Date:
**Re: Allegro CL Floating Point** - Previous by thread:
**Allegro CL Floating Point** - Next by thread:
**Allegro CL Floating Point** - Index(es):