[Openmcl-devel] Optimization and safety declarations

Raffael Cavallaro raffaelcavallaro at mac.com
Wed Jan 21 15:09:44 PST 2004

I've come across a benchmark on the net that determines whether a point 
is in a polygon. I've appended the source below. It's also available 
(see page 5 for lisp source)

When compiled with:
(declare (optimize (speed 3) (safety 0))…
it generates fast code, but the result is wrong - the final output 
should be 60000, but it returns 80000 with safety 0.
(declare (optimize (speed 3) (safety 1))…
generates code that takes about 50% longer to run, and produces the 
correct result. All of these optimization settings refer to the first 
function, pnpoly, not the test function, pnpolytest.
I've looked at the disassembly, but, to be honest, I can't tell why it 
is that the generated code is incorrect for the safety 0 optimization 
declaration - (this should be unsurprising because I know next to 
nothing about reading lisp disassembly).

What is OpenMCL doing when safety is declared 0, that causes incorrect 
code to be generated? Is this just a risk of using the safety 0 
setting, or is this some sort of bug in OpenMCL's code generation? BTW, 
sbcl is just as fast with safety 0 as OpenMCL, but generates correct 
code, at least to judge from the output.

------------ begin pnpoly.lisp --------------------

(defun pnpoly (npol xp yp x y)
   (declare (optimize (speed 3) (safety 0)) (fixnum npol) (double-float 
x y)
    (type (simple-array double-float (*)) xp yp))
   (let* ((c nil) (j (1- npol)))
     (declare (fixnum j))
     (dotimes (i npol c)
       (declare (fixnum i))
       (if (and (or (and (<= (aref yp i) y) (< y (aref yp j)))
                    (and (<= (aref yp j) y) (< y (aref yp i))))
                (< x
                   (+ (aref xp i)
                      (/ (* (- (aref xp j) (aref xp i)) (- y (aref yp 
                         (- (aref yp j) (aref yp i))))))
           (setq c (not c)))
       (setq j i))))

(defun pnpolytest ()
   (declare (optimize (speed 3) (safety 0)))
   (let ((npol 20)
         (count 0)
          (make-array 20
                      '(0.0d0 1.0d0 1.0d0 0.0d0 0.0d0 1.0d0 -0.5d0 
-1.0d0 -1.0d0
                        -2.0d0 -2.5d0 -2.0d0 -1.5d0 -0.5d0 1.0d0 1.0d0 
                        -0.5d0 -1.0d0 -0.5d0)))
          (make-array 20
                      '(0.0d0 0.0d0 1.0d0 1.0d0 2.0d0 3.0d0 2.0d0 3.0d0 
                        -0.5d0 -1.0d0 -1.5d0 -2.0d0 -2.0d0 -1.5d0 -1.0d0 
                        -1.0d0 -1.0d0 -0.5d0))))
     (declare (fixnum npol count) (type (simple-array double-float (20)) 
xp yp))
     (dotimes (i 100000)
       (if (pnpoly npol xp yp 0.5d0 0.5d0) (incf count))
       (if (pnpoly npol xp yp 0.5d0 1.5d0) (incf count))
       (if (pnpoly npol xp yp -0.5d0 1.5d0) (incf count))
       (if (pnpoly npol xp yp 0.75d0 2.25d0) (incf count))
       (if (pnpoly npol xp yp 0.0d0 2.01d0) (incf count))
       (if (pnpoly npol xp yp -0.5d0 2.5d0) (incf count))
       (if (pnpoly npol xp yp -1.0d0 -0.5d0) (incf count))
       (if (pnpoly npol xp yp -1.5d0 0.5d0) (incf count))
       (if (pnpoly npol xp yp -2.25d0 -1.0d0) (incf count))
       (if (pnpoly npol xp yp 0.5d0 -0.25d0) (incf count))
       (if (pnpoly npol xp yp 0.5d0 -1.25d0) (incf count))
       (if (pnpoly npol xp yp -0.5d0 -2.5d0) (incf count)))
     (princ "count ")
     (princ count)

----------- end pnpoly.lisp ----------------------

Raffael Cavallaro, Ph.D.
raffaelcavallaro at mac.com

More information about the Openmcl-devel mailing list