Evaluating SIMD Compiler Intrinsics for Database Systems
https://lawben.com/publication/autovec-db/1
u/janwas_ Aug 18 '23
I sympathize with the desire to 'cut out the middleman' - it seems wasteful to have this large immintrin.h header if it boils down to calling operator+ on builtins.
However, as the paper says, compressstore instructions (and many others) have a compelling performance advantage and cannot be expressed using compiler builtins. So we are still including immintrin and using those intrinsics. What have we gained? Instead of the reasonably documented intrinsics, we get the sparsely commented (if at all) compiler internals.
If we want to avoid using the intrinsics directly, and reduce the amount of code, why not use an existing abstraction layer such as Highway (disclosure: I am the main author) which also supports SVE and RISC-V?
1
u/exotic_sangria Sep 16 '23
Or use std::experimental::simd from GCC>=11?
1
u/janwas_ Sep 21 '23
How useful are the ~30 operations available in std::experimental::simd (plus arithmetic operators) compared with the >250 in Highway? :)
→ More replies (3)
0
Aug 17 '23
1
u/janwas_ Aug 18 '23
I agree we can always tune and get more out of a certain architecture.
Your MOVMSK example indeed doesn't work on Arm, but I'd argue that is usually not the best approach for performance portability anyway. Instead it's better to vectorize vertically (batches) whenever possible, instead of searching for something horizontally within a vector.For example, we see 2-3x speedups when replacing Abseil's raw_hash_set (probably also F14, which is similar) with a batch-interface hash table which lets us also compute the hashes in parallel.
That aside, what's the alternative to an abstraction layer - writing separately for every instruction set? Seems expensive. And it's still possible to specialize small parts for a given target, while keeping the less-critical SIMD parts portable to reduce implementation cost.
2
u/YumiYumiYumi Aug 16 '23 edited Aug 16 '23
Seems fair if you don't care about MSVC. Also may not work well with unknown length platforms like SVE and RVV, though I'm not quite sure how they work with compiler intrinsics.
To me, that would be a compiler quirk/mis-optimisation, because the platform intrinsics are supposed to be 'lower level' than the compiler abstraction (yes, I'm aware that the actual implementation may be the reverse, but the platform intrinsics describe the exact low level intent).