Re: Unboxed structures (yes, again, only this time for real)
"Yuri Davidovsky (as work at disclosure dot ie)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
> On 16 Jan 2026, at 11:00, Tim Bradshaw <[email protected]> wrote: > > Note that *all your fields are immediate types on a 64-bit implementation*. You are not going to get boxing in any case, because none of these objects will be boxed. Well, just to clear it out straight away, that does not say that data cannot be inlined within a struct body and is always boxed, does it? Additionally, what does ’none of these objects will be boxed’ mean exactly? Does it mean the bit tags will be removed? If so, why can they be removed for single floats, but not for doubles? The default pointer size of 8 bytes allows that. Or are they still tagged, but the values not located on the heap (except doubles, which are located on the heap)? Something doesn’t add up here. > In particular the object size of a PARTICLE is 80 bytes, which is 8 64-bit fields and two words (16 bytes) of header. The size would be the same for a double-float version. I will try to do some digging in the raw bytes with FLI to see what exactly is stored in an array of particles to get a clear answer. There is no need to speculate here. > If you poke around with arrays, you'll find that a single-float array is asymptotically half as large as it will place the single-floats on half-word boundaries (you get an unused half-word if the array has an odd number of elements). I will just see what FLI experiments show. >> >> ;; Initialize array of particles >> (defparameter *particles* (make-array +num-particles+ :element-type 'particle)) > > And now > > ? (array-element-type *particles*) > t > > In other words, this is an array of pointers: the structures are not, and cannot be for reasons of object identity, stored in the array. Lisp is notoriously very loose on types and that alone does not say much to me personally without seeing some ground truth on the byte level. However it could be correct that the particle array was indeed an array of pointers. The reason why they were performing as fast as a contiguous array of custom structs could be because the structs themselves were a) packed, while making a discount to the fact that, as you said, that does not work for doubles, but I only used 32 bit data types, so according to what you say, the structs' field values should be immediate (and untagged/unboxed?) making access easy. b) since the structs were initialised and allocated in a continuous region in the heap, the prefetcher may have figured it out from the memory access pattern and could optimise for it (but this is a speculation). PS: I am adding the list back into the CC because if my conclusions were incorrect, no-one should be misled by the findings. Additionally I restarted the lisp image this morning and cannot get the same test results now, I am seeing something strange where performance of either type of the struct fluctuates wildly depending on the number iterations in the test, the difference can be multiples faster of one type of struct over another, without any real rhyme or reason. I am not sure what it is, something probably got borked in the image yesterday before restart, or today after, so I will just look into the bytes using FLI, that would be the easiest solution. _______________________________________________ Lisp Hug - the mailing list for LispWorks users [email protected] http://www.lispworks.com/support/lisp-hug.html