Lisp HUG Maillist Archive

sqrt causes consing ???

hi,

i am trying to optimize some vector operations in lisp, and i seem to  
have run into a wall:

----------------------------8<----------------------------------
(deftype vec3f ()
   `(simple-array single-float (3)))

(defun make-vec3f (&rest args)
   (if args
     (make-array 3 :element-type 'single-float :initial-contents args)
     (make-array 3 :element-type 'single-float :initial-element 0.0f0)))

(declaim (inline vec3f-length))
(defun vec3f-length (v)
   (declare (type vec3f v)
            (optimize (speed 3) (debug 0) (safety 0) (float 0)))
   (let* ((a0 (aref v 0))
          (a1 (aref v 1))
          (a2 (aref v 2))
          (sq (+ (* a0 a0)
                 (* a1 a1)
                 (* a2 a2))))
     (declare (type single-float a0 a1 a2 sq))
     (the single-float (sqrt sq))))


(defun test ()
   (declare (optimize (speed 3) (safety 0) (debug 0) (float 0)))
   (let ((v (make-vec3f 1.0 2.0 3.0)))
     (dotimes (i 1000000)
       (vec3f-length v))))
----------------------------8<----------------------------------

running (time (test)) shows some considerable consing (approx 16  
bytes per iteration).  when i replace the "(sqrt sq)" with "sq", the  
consing stops.  so i am guessing the sqrt case somehow boxes it's  
floats while the non-sqrt case does not.

how do i get this to stop consing?

i see this behaviour with lispworks professional 4.4.6 (linux) and  
lispworks personal 4.4.6(mac).

regards,
juergen

-- 
Juergen Gmeiner <gj@gjdv.at>




Re: sqrt causes consing ???

If you disassemble the compiled function you see the
boxing of sq for the sqrt function.  (line 83).  I do
not think there is anything you can do to make sqrt
inline.

Wade

CL-USER 8 > (disassemble 'vec3f-length)
211DCA32:
       0:      55               push  ebp
       1:      89E5             move  ebp, esp
       3:      83EC20           sub   esp, 20
       6:      C7042445200000   move  [esp], 2045
      13:      D94010           flds  [eax+10]
      16:      DD5DEC           fstpl [ebp-14]
      19:      D94014           flds  [eax+14]
      22:      DD5DE4           fstpl [ebp-1C]
      25:      D94018           flds  [eax+18]
      28:      DD5DF4           fstpl [ebp-C]
      31:      DD45EC           fldl  [ebp-14]
      34:      DC4DEC           fmull [ebp-14]
      37:      DD5DEC           fstpl [ebp-14]
      40:      DD45E4           fldl  [ebp-1C]
      43:      DC4DE4           fmull [ebp-1C]
      46:      DD5DE4           fstpl [ebp-1C]
      49:      DD45F4           fldl  [ebp-C]
      52:      DC4DF4           fmull [ebp-C]
      55:      DC45E4           faddl [ebp-1C]
      58:      DC45EC           faddl [ebp-14]
      61:      DD5DF4           fstpl [ebp-C]
      64:      83EC0C           sub   esp, C
      67:      C70424450C0000   move  [esp], C45
      74:      DD45F4           fldl  [ebp-C]
      77:      DD5C2404         fstpl [esp+4]
      81:      B501             moveb ch, 1
      83:      FF1530671120     call  [20116730]       ; 
SYSTEM::RAW-FAST-BOX-DOUBLE
      89:      B501             moveb ch, 1
      91:      C9               leave
      92:      FF2560D30020     jmp   [2000D360]       ; SQRT
NIL

CL-USER 9 >

Juergen Gmeiner wrote:
>
> hi,
>
> i am trying to optimize some vector operations in lisp, and i seem to 
> have run into a wall:
>
> ----------------------------8<----------------------------------
> (deftype vec3f ()
>   `(simple-array single-float (3)))
>
> (defun make-vec3f (&rest args)
>   (if args
>     (make-array 3 :element-type 'single-float :initial-contents args)
>     (make-array 3 :element-type 'single-float :initial-element 0.0f0)))
>
> (declaim (inline vec3f-length))
> (defun vec3f-length (v)
>   (declare (type vec3f v)
>            (optimize (speed 3) (debug 0) (safety 0) (float 0)))
>   (let* ((a0 (aref v 0))
>          (a1 (aref v 1))
>          (a2 (aref v 2))
>          (sq (+ (* a0 a0)
>                 (* a1 a1)
>                 (* a2 a2))))
>     (declare (type single-float a0 a1 a2 sq))
>     (the single-float (sqrt sq))))
>
>
> (defun test ()
>   (declare (optimize (speed 3) (safety 0) (debug 0) (float 0)))
>   (let ((v (make-vec3f 1.0 2.0 3.0)))
>     (dotimes (i 1000000)
>       (vec3f-length v))))
> ----------------------------8<----------------------------------
>
> running (time (test)) shows some considerable consing (approx 16 bytes 
> per iteration).  when i replace the "(sqrt sq)" with "sq", the consing 
> stops.  so i am guessing the sqrt case somehow boxes it's floats while 
> the non-sqrt case does not.
>
> how do i get this to stop consing?
>
> i see this behaviour with lispworks professional 4.4.6 (linux) and 
> lispworks personal 4.4.6(mac).
>
> regards,
> juergen
>
> --Juergen Gmeiner <gj@gjdv.at>
>
>
>
>


Re: sqrt causes consing ???

Unable to parse email body. Email id is 5237

Re: sqrt causes consing ???


On Jan 23, 2006, at 5:28 AM, Duncan Harvey wrote:
>> how do i get this to stop consing?
>
> One has to promise that SQRT's argument is non-negative, e.g.:
>
>   ... (sqrt (the (single-float 0.0) sq)) ...
>
> This causes a specialised, non-consing version of SQRT to be used.
> Otherwise the general SQRT (which can, for example, return complex
> numbers when given negative arguments) gets called as usual.

works like a charm!

thanks you very much,
juergen

-- 
Juergen Gmeiner <gj@gjdv.at>




Updated at: 2020-12-10 08:49 UTC