Re: memory usage issue for double-float operations
Matt Kaufmann <[email protected]>
| Newsgroups | gmane.lisp.steel-bank.general |
|---|---|
| Message-ID | <[email protected]> |
Very interesting. I expected the declare form in the defun of
my-update --
(declare (type (simple-array double-float (*)) ar)
(type double-float v))
-- to avoid boxing. As another experiment I added the following just
before the defun of my-update -- but consing still occurred.
(declaim (ftype (function ((simple-array double-float (*)) t double-float)
double-float)
my-update))
Apparently those extra efforts don't change your point about boxing,
which contradicts what I thought I understood. I appreciate the help!
Thanks,
Matt
Michał "phoe" Herda <[email protected]> writes:
> Converting a double float to a function argument requires boxing, which
> allocates memory. If the function is inlined, there are no arguments to
> pass, so there can be no consing.
>
> On 26.09.2024 01:55, Matt Kaufmann wrote:
>> Thanks so much!
>>
>> I see that suitable THE declarations also avoid consing. But
>> inserting a function call can cause consing, whether using THE or your
>> declaim form, as illustrated below. I'd be interested in any insights
>> about why that function call causes consing.
>>
>> (declaim (optimize (compilation-speed 0) (debug 0) (speed 3) (space 0)
>> (safety 0)))
>>
>> ; Optional:
>> ; (declaim (type (simple-array double-float (5000)) *ar*))
>>
>> (defvar *ar* (make-array '(5000)
>> :element-type 'double-float
>> :initial-element 0.0d0))
>>
>> (loop with i of-type (integer 0 *) = 0 do
>> (cond ((>= i 5000)
>> (return))
>> (t (progn (setf (aref *ar* i)
>> (float i 0.0d0))
>> (setq i (1+ i))))))
>>
>> (defun foo (ar)
>> (loop with i = 0 do
>> (cond
>> ((>= i 4999) ; <-- for i from 0 to 4999 ...
>> (return))
>> (t (setf (aref (the (simple-array double-float (*)) ar)
>> i)
>> (the double-float
>> (+ 1.0d0
>> (the double-float
>> (aref (the (simple-array double-float *) ar)
>> i)))))
>> (setq i (1+ i))))))
>>
>> (time (foo *ar*)) ; 0 bytes consed
>>
>> ; Optional:
>> (declaim (inline my-update))
>>
>> (defun my-update (ar i v)
>> (declare (type (simple-array double-float (*)) ar)
>> (type double-float v))
>> (setf (aref (the (simple-array double-float (*)) ar)
>> i)
>> v))
>>
>> (defun foo2 (ar)
>> (loop with i = 0 do
>> (cond
>> ((>= i 4999) ; <-- for i from 0 to 4999 ...
>> (return))
>> (t (my-update ar
>> i
>> (the double-float
>> (+ 1.0d0
>> (the double-float
>> (aref (the (simple-array double-float *)
>> ar)
>> i)))))
>> (setq i (1+ i))))))
>>
>> (time (foo2 *ar*)) ; 65,536 bytes consed if not inlined, 0 otherwise
>>
>> Thanks,
>> Matt
>> Michał "phoe" Herda <[email protected]> writes:
>>
>>> (declaim (type (simple-array double-float (5000)) *ar*))
>>>
>>> On 25.09.2024 21:44, Matt Kaufmann wrote:
>>>> Hi,
>>>>
>>>> Is there a way to modify the example below so that the final form does
>>>> not allocate memory in SBCL? (To be fair, I tried several other Lisps
>>>> as well, and all of them allocated memory.)
>>>>
>>>> (declaim (optimize (compilation-speed 0) (debug 0) (speed 3) (space 0)
>>>> (safety 0)))
>>>>
>>>> (defvar *ar* (make-array '(5000)
>>>> :element-type 'double-float
>>>> :initial-element 0.0d0))
>>>>
>>>> (loop with i of-type (integer 0 *) = 0 do
>>>> (cond ((>= i 5000)
>>>> (return))
>>>> (t (progn (setf (aref *ar* i)
>>>> (float i 0.0d0))
>>>> (setq i (1+ i))))))
>>>>
>>>> (defun foo ()
>>>> (loop with i of-type fixnum = 0 do
>>>> (cond
>>>> ((>= i 4999) ; <-- for i from 0 to 4999 ...
>>>> (return))
>>>> (t (setf (aref *ar* i)
>>>> (the double-float
>>>> (+ 1.0d0
>>>> (the double-float (aref *ar* i)))))
>>>> (setq i (the fixnum (1+ i)))))))
>>>>
>>>> (time (foo))
>>>>
>>>> Thanks,
>>>> Matt
>>>>
>>>>
>>>> _______________________________________________
>>>> Sbcl-help mailing list
>>>> [email protected]
>>>> https://lists.sourceforge.net/lists/listinfo/sbcl-help
_______________________________________________
Sbcl-help mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-help