5 ms·
Great article, and it’s pretty interesting to see portable simd in use. I tried reproducing the benchmarks on a Zen 3 system, and I’m getting identical speedups
by dist1ll 3y ago
Great article, and it’s pretty interesting to see portable simd in use. I tried reproducing the benchmarks on a Zen 3 system, and I’m getting identical speedups. On my M1 mbp, the perf gains start around 1.4x, gradually increasing to 2x @ 110 bytes of input length. A bit less gains than on x86_64, but I’d say it fulfils its goal.
Although looking at the code, this article confirms my experience that Rust has rather poor ergonomics for simd and pointer-related work (and performance engineering in general).
- pcwalton 3y agoI disagree with the ergonomics being poor. C++ SSE intrinsics are significantly worse, with ugly underscores and names that are hard to remember.
- dist1ll 3y agoBeing more ergonomic than C++ is a low bar anyways, we should hold ourselves to a higher standard. For starters, field offset syntax is painful (see Gankra's post on this topic) and pointer manipulation lacks syntactic sugar. I also believe unsigned integer promotion and UFCS would improve ergonomics with high-perf code (although I'm aware this is not going to be included in Rust).
- lifthrasiir 3y agoAt that point it is better to have some kind of DSL that should not be in the main language, because it would target a much lower level than a typical program. The best effort I've seen in this scene was Google's Highway [1] (not to be confused with HighwayHash) and I even once attempted to recreate it in Rust, but it is still a bit far from my ideal. [1] https://github.com/google/highway https://github.com/google/highway
- janwas 3y agoThanks :) We're always curious to hear how it could be improved?
- lifthrasiir 3y agoI think Highway is already good enough as a non-DSL. I had something like GLSL in mind, but more blended to the parent language.
- superjan 3y agoI agree about having a DSL. It may not need to be low level, you could have an array language like APL/J. But glsl would work for me too, the important thing is to lure developers to expose parallelism.
- dzaima 3y agoThe kind of things you can use direct SIMD for is a reasonably-different space than array languages; while some things can translate reasonably, APL-likes get much less pretty on operations where elements don't have homogeneous meaning/mapping, e.g.: the base64 conversion of OP. (for reference, I work on https://github.com/dzaima/CBQN https://github.com/dzaima/CBQN, an implementation of BQN, an APL derivative, and we have a DSL for implementing SIMD primitives for it (and sometimes scalar ones too): https://github.com/mlochbaum/Singeli https://github.com/mlochbaum/Singeli)
- flohofwoe 3y agoCheck out the Clang extended vector extension for C, IMHO that's the perfect way to add portable SIMD to a language. Doing it through a library will always be clumsy.
- lifthrasiir 3y agoIt quickly runs into __builtin functions though, which is not very different from intrinsics with a better and portable name. Rust `Simd` type is much more consistent with corresponding scalar types compared to that.
- flohofwoe 3y agoTrue, I think the builtins were necessary where the existing C operators don't map well to a specific SIMD feature (from what I've seen it's mostly "reduce" actions to reduce SIMD lanes into a single value). Still, a lot can be done without having to pepper the code with builtin functions, and the result is much more readable than purely intrinsic-based code. But a "new" language like Rust would have the freedom to add special language syntax and operators for such things instead of going the C++ way of "just add it to the stdlib" (which IMHO is almost always the wrong place... it should either go into a regular cargo dependency, or into the language itself).
- vt240 3y agoI loved the Intel Cilk Plus project. I was sad to see it was abandoned. It always felt like a very natural syntax at least to me.
- secondcoming 3y agoThose intrinsics are specified by Intel, not C++
- bottled_poe 3y agoAs if semantics are a significant productivity factor, get off ya high horse.
- cmrdporcupine 3y agoHaven't read through the article yet, but as a Rust eng... I sort of agree, but ... I mean, pointer & raw memory related work is deliberately kneecapped in the name of safety, the language wants you to really think about what you're doing. But yep portable SIMD in Rust is still not a good story, compared to C++. And getting down to raw byte regions, pointer & buffer manipulation, etc requires becoming comfortable with Pin, MaybeUninit, etc. Both portable simd and allocator_api have been sitting unstable for years. And the barrier to entry is a bit higher, and it's more awkward ... mostly on purpose But there's nothing stopping one from building one's own abstractions (or using 3rd party crates etc) to make these things more ergonomic within one's own program?