rif <[EMAIL PROTECTED]> writes:

> I'm trying to optimize the following function (yes, profiling
> indicates that this function is the bottleneck, it's taking the lion's
> share of the time and the consing).
> 
> (defun find-closest-index (point centers)
>   (declare (type simple-array centers)
>            (type (simple-array double-float) point))
>   (let ((best-dist most-positive-double-float)
>         (dist 0.0d0)
>         (index -1))
>     (declare (type fixnum index)
>              (type double-float best-dist)
>            (type double-float dist))
>     (fixtimes (i (array-dimension centers 0))
>        (let ((c (aref centers i)))
>          (declare (type (simple-array double-float) c))
>        (setf dist (the double-float (l2-distance-squared point c)))
>          (when (< dist best-dist)
>            (progn
>              (setf index i)
>              (setf best-dist dist)))))
>     index))
> 
> 
> One of the compiler notes (settings were speed 3, debug and safety 0)
> for this function is:
> 
> ;   (SETF BEST-DIST DIST)
> ; ==>
> ;   (SETQ BEST-DIST DIST)
> ; Note: Doing float to pointer coercion (cost 13) from DIST to BEST-DIST.
> 
> And I cannot for the life of me figure out why I'm getting this.  Any
> ideas?

Under CMUCL (not SBCL) this variant seems to work:

(defun find-closest-index (point centers)
  (declare (optimize (speed 3) (debug 0) (safety 0)))
  (declare (type (simple-array * 1) centers)
           (type (simple-array double-float 1) point))
  (let ((best-dist most-positive-double-float)
        (dist 0.0d0)
        (index -1))
    (declare (type fixnum index)
             (type double-float best-dist)
             (type double-float dist))
    (setq best-dist (- (- best-dist)))   ; <-----------------------------!!!
    (flet ((l2-distance-squared (a1 a2)
             (loop for x double-float across a1
                   and y double-float across a2
                   summing (expt (- x y) 2) of-type double-float)))
      (dotimes (i (array-dimension centers 0))
        (declare (fixnum i))
        (let ((c (aref centers i)))
          (declare (type (simple-array double-float 1) c))
          (setf dist (the double-float (l2-distance-squared point c)))
          (when (< dist best-dist)
            (progn
              (setf index i)
              (setf best-dist dist))))))
    index))

In general try to add some simple FP operations with the problematic
variable and hope the compiler will not be able to optimize them away.

-- 
Regards,
Alexey Dejneka

"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer

Reply via email to