Re: I wonder if I'm missing something...
"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
I don’t believe that you can do faster than this whole vector copy approach using READ-BYTE. You still have to convert every 4 bytes into a SINGLE-FLOAT. FLI:REPLACE-FOREIGN-ARRAY is very fast. > On Nov 9, 2025, at 02:58, David McClain (as dbm at refined-audiometrics dot com) <[email protected]> wrote: > > Well, I will only disagree with your counting. > > The original, and now current, method does READ-SEQUENCE into a vector of ‘(unsigned-byte 8). From there, the bytes are copied into an FLI Foreign Array with element type :UINT8, and from there another FLI Foreign Array copy from FLI space back to Lisp with a coerced pointer to the same FLI arena, and with element types :FLOAT and Single-Float. > > So > I/O -> Lisp -> FLI -> Lisp > >> On Nov 9, 2025, at 02:44, Yuri Davidovsky (as work at disclosure dot ie) <[email protected]> wrote: >> >> >>> On 8 Nov 2025, at 23:21, David McClain (as dbm at refined-audiometrics dot com) <[email protected]> wrote: >>> >>> 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)) >> >> I am not quite sure you are achieving what you think you are achieving here, it seems like you are making even more copying than there was at the start. As I understand it, the data from sockets gets to LW by these steps: >> >> 1. Data is written to the kernel’s network buffer. We are not involved here in any way. >> 2. A kernel call to recv() from LW fills the underlying buffer of the socket-stream by copying from the network buffer. No way to avoid copying here (sort of, kinda possible in Linux). >> 3. You copy data from the stream into your own buffer making Lisp calls to read-byte and read-sequence. >> >> There is only one “unneeded” copying at step 2 but it is needed if you want to work with a Lisp stream. Since read-sequence does not work in your case, so you just should use read-byte and go on about your day. If you really do not want to use read-byte here, then you just patch into the step 2 with your own buffer and avoid using the Lisp byte stream altogether. >