[Openmcl-devel] Optimization and safety declarations
Raffael Cavallaro
raffaelcavallaro at mac.com
Wed Jan 21 23:09:44 UTC 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
at:
<http://openmap.bbn.com/~kanderso/performance/postscript/in-poly.ps>
(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.
TIA,
raf
------------ 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
i)))
(- (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)
(xp
(make-array 20
:element-type
'double-float
:initial-contents
'(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.0d0
-0.5d0 -1.0d0 -0.5d0)))
(yp
(make-array 20
:element-type
'double-float
:initial-contents
'(0.0d0 0.0d0 1.0d0 1.0d0 2.0d0 3.0d0 2.0d0 3.0d0
0.0d0
-0.5d0 -1.0d0 -1.5d0 -2.0d0 -2.0d0 -1.5d0 -1.0d0
-0.5d0
-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)
count))
----------- end pnpoly.lisp ----------------------
Raffael Cavallaro, Ph.D.
raffaelcavallaro at mac.com
More information about the Openmcl-devel
mailing list