Re: I wonder if I'm missing something...

Martin Simmons <[email protected]>
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
Yes, the problem is that the compiler doesn't know how to stack allocate
vectors with element-type (unsigned-byte 8).

-- 
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/



>>>>> On Sun, 9 Nov 2025 02:50:45 -0700, David McClain (as dbm at refined-audiometrics dot com) said:
> 
> Well, bad idea… Doing the shortcut, assuming that buffer doesn’t move under GC, seems to be incorrect. I am seeing sporadic errors that could only be attributable to the presumed buffer pointer being incorrect, and furnishing :NAN and other nasty surprises on rare occasions.
> 
> 
> 
> > On Nov 8, 2025, at 15:18, David McClain (as dbm at refined-audiometrics dot com) <[email protected]> wrote:
> > 
> > I found that by using some unmentioned details about the LWM implementation, I could avoid one whole buffer copy in the operation. The high level Lisp way uses 2 whole buffer copies - Lisp to FLI, FLI back to Lisp, to effect the transformation from byte vector to float vector.
> > 
> > But here are details you aren’t supposed to care about:
> > 
> > (let ((buf (make-array 1
> >                        :element-type    '(unsigned-byte 8)
> >                        :initial-element #xAA)))
> >   (declare (dynamic-extent buf))
> >   (loenc:dump (sys:object-address buf) 40))
> > 
> > ____   0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F
> > 0000  36 2B 00 00  08 00 00 00  AA AA AA AA  AA AA AA AA  6+......ªªªªªªªª
> > 0010  36 2B 00 00  40 01 00 00  55 55 55 55  55 55 55 55  [email protected]
> > 0020  55 55 55 55  55 55 55 55                            UUUUUUUU
> > 
> > Byte #4 shows the length of the array, here just 1 element. There must be 3 tag bits on Fixnums. But the array arena has 8 of them, all initialized to my initial element #xAA, starting at offset 8 from the object address.
> > 
> > So the interesting thing is that you can’t allocate anything but chunks of memory 8 bytes long. And even though my array has only one element, the system allocated 8 of them and initialized them too.
> > 
> > But the takeaway is that a simple raw array has an 8 byte prefix at the address given by SYS:OBJECT-ADDRESS. And by declaring the buffer to have DYNAMIC-EXTENT, we force the array to live on the system stack, and not move due to GC (unless the stack gets relocated….)
> > 
> > So now, I can read :UINT8 bytes from a Socket stream, directly into a stack allocated octet buffer, then turn around and use the FLI:REPLACE-FOREIGN-ARRAY to convert that buffer of octets into a buffer of single-float values in just one copy operation:
> > 
> > 	(let ((buf   (make-array  16
> >                                   :element-type ‘(unsigned-byte 8))))
> > 	   (declare (dynamic-extent buf))
> > 	   (READ-SEQUENCE buf socket-stream)
> > 	   (FLI:REPLACE-FOREIGN-ARRAY my-float-vec (fli:make-pointer :type :FLOAT
> >                                                                      :address (+ 8 (SYS:OBJECT-ADDRESS buf)))
> >                                       :end2 4))
> > 
> > 
> 
> 

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.