Re: LW compiler optimizations
"Yuri Davidovsky (as work at disclosure dot ie)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
On 15 Jan 2025, at 16:19, David McClain <[email protected]> wrote: But I think we are also looking at the difference between open coded scalar computations in my C code, versus possible low-grade SIMD in vDSP. (??) The vDSP functions have been implemented in two ways: as vectorized code, which uses vector instructions (SSE3, for example) in the processor, and as scalar code, which does not. The vDSP API uses the appropriate version depending on the arguments given and the vector capabilities of the processor. About the vDSP API developer.apple.com https://developer.apple.com/library/archive/documentation/Performance/Conceptual/vDSP_Programming_Guide/About_vDSP/About_vDSP.html#//apple_ref/doc/uid/TP40005147-CH2-SW1 My best Lisp timing was about 1.1 ns/MAC pair on AMD, versus 1.4 μs/MAC pair on M1. That shows the two machines to be competitive. These numbers are close enough, in my mind, to consider them equal. Variations in cache configurations, background task loads, etc, might well make a ±20% variation in timings on any one machine. But my timings also indicate a realistic performance in live settings. The measurements seem high for M1, I was consistently getting below 1ns timings per pair in Bradshaw’s code. Overall, the biggest takeaway, for me, in writing efficient Lisp code, is to maximize the possibility for SIMPLE-1D-ARRAY of specialized types, use in-line index offset calculations, instead of compound looping, e.g.: I did not quite get the simple-1d-array thing. It appears that using simple type arrays works just fine. Pinnable allocation should be used when sending it over fli however. The compound loop is 2-3x slower than the direct DOTIMES code. For some reason Bradshaw’s code shows slightly better performance for ‘do’ loops. Not sure why dotimes being a simpler loop construct would be producing worse timings. And avoid the inherent displaced array opportunities presented by Common Lisp. Tim recognized this cost, and created his own specialized macro for these restricted kinds of displaced arrays. This is one of the interesting findings of this discussion: do not use displaced arrays in Lisp (or at least in LW, not too sure how SBCL handles that). I find it curious since before that I assumed that a displaced array is no different to a regular array, with it just being another struct that refers to the same memory area as the original array. Apparently, that is not the case and it can bite when you least expect it. I’m happy that in many cases, Lisp can produce very competitive code. But for the most important primitives across large collections, nothing can beat specialized library routines. I would say the only reason to go a specialised route is when you need vectorisation support, or you need to send the workload to a GPU. If you are okay with scalar operations, you might as well stay in lisp if having to deal with declarations does not bother you.
apple-touch-icon-precomposed.png
(image/png, 15.4 KB) - not displayed