

Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- > When Google needed portable SIMD for production image and video codecs, they built Highway — not std::simd.
Sure, they left the committee years ago. I am not trying to claim any sort of direct causality, but it sure seems like this is a case where Google's presence on the committee might have prevented shipping boondoggles like this. Modules is another case where I think Google's feedback might have been able to steer the ship in a better direction.
by StilesCrisis - They probably left the committee because it keeps going in circles rather than solving the issues of the languageby raverbashing
- Agreed, fixed with vectors needs to be a language feature, better compile times and would solve issues for most people.
Personally, I think that like Clang way to adding GLSL like vectors and semantics would've gone a long way. SVE might be an elegant design, but in reality there are probably a multiple factor of game and other 3d code being written that needs vectors compared to other fields, and there limited vector sizes aren't really a problem.
And honestly, considering the story of AVX512.. with 512 bit vectors being removed from mainstream by Intel, do we really really need longer ones despite it being from a "scalable design"?
by whizzter - In GPUs GLSL like types compile down to what basically is variable length SIMD. A vec4 doesn't get compiled to a SIMD vector with four floats, but rather to four SIMD vectors, each containing N FP32 elements (usually 32 or 64).
Look at what this simple shader compiles down to on RGA: https://godbolt.org/z/4GrfY61vf
by camel-cdr - Intel has been forced to reintroduce 512-bit vectors in the mainstream, because of the competition from AMD.
Starting with the Intel Nova Lake CPUs, around the end of this year, all future AMD and Intel CPUs will provide 512-bit vectors, like also the current AMD Zen 5 and Zen 4 CPUs.
The 512-bit vector length is more convenient than other lengths, because on the AMD and Intel CPUs it coincides with the length of a cache line. Because of this, it is easier to optimize simultaneously for the best cache usage.
For GPUs, which favor throughput over latency, 1024-bit and 2048-bit vector register widths are frequently used. For CPUs it is unlikely that widths greater than 512-bit would be useful, as the vector operations that should be done on CPUs are those for which the high latency of using a GPU is undesirable.
by adrian_b - If you thought std::simd was a library nobody asked for, just wait until you hear about <linalg>. I feel like half the people looking forward to that think they're just going to get standard C++ bindings to LAPACK, when instead they're probably going to get an unoptimized, slapdash implementation of LAPACK written by people who aren't good at BLAS.
As for SIMD itself, designing a good SIMD library is difficult because there are several different SIMD approaches and some of them work poorly for certain use cases. For example, you can take an HPC-ish approach of "vectorize this loop" (à la #pragma omp simd) and have the compiler take care of a fairly mechanical transformation. Or you can take an opposite approach of treating a 128-bit SIMD vector as a fundamental data type in your language. Which approach is better depends on your use case.
by jcranmer - are u carefully read <linalg> paper[1]?
It doesn't require to reimplement it...
> Our proposal is inspired by and extends the dense BLAS interface. A natural implementation might look like this:
> 1. wrap an existing C or Fortran BLAS library,
[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p16...
by feelamee - Just wait until you hear about std::hive.
The work of one obsessive author, who never gave a good explanation for why the thing needed to be in the standard library instead of an external one. The committee was apathetic about the proposal and kept bringing up various trivial issues, in a clear attempt to stall him, but he refused to take the hint. So eventually they relented. Outside coverage I have seen so far seems to be to the tune of "WTF is this weird thing?" and quickly glosses over it.
I wonder if it's going to end up like the export keyword.
- Just write inline asm for x86 and aarch64 (if you care about that) and not care about the rest. Is it even useful to do simd on other processors?
Compiler optimizing even the code around the simd code based on the semantics of arithmetic or other things sounds silly after writing some of this kind of code
by ozgrakkurt - So you "just" write 4 assembly implementations?by camel-cdr
- Curious if people here have looked at the upcoming SIMD support in Go: https://go.dev/doc/go1.26#simd
Currently experimental, but looks like the first Intel arch will arrive in the next release in about 3 months. They are also going to support a portable layer.
Wondering what people here think about the approach the Go team is taking; I think they would appreciate more eyeballs on their design. (I’m not competent in this space (yet))…
by meling - Also here is an example of some Go and the Asm code generated:
https://godbolt.org/z/n8hKhc7rY
(click the recompile button if you don't see the Asm code)
by aphillips801 - Looks like that isn't a portable SIMD abstraction, but more similar to adding architecture-specific SIMD intrinsics support to go, with nicer syntax.by camel-cdr
- I did a lot of experimentation with the Go1.26 experiment. It's easy to use and produces good code but only supports x86 ATM. (See https://andrewwphillips.github.io/blog/go1p26.html#simd-expe...)
I think there will be a "portable" wrapper that will also support other architectures (arm, riscv, even wasm) in the future based on the Highway C++ library.
by aphillips801 - One thing I will point out is that the code in the article is compiled with `-march=native` and `-ffast-math`, meaning that they're really only compiling for the exact same machine they are running on and no other. This seems like it is mainly applicable to places which can easily recompile code for the exact known hardware that they run on, such as HFT and some scientific computing.
Places which compile code to distribute for people to run on a variety of processors and platforms (or that require floating point code to be consistent between them), i.e. games and applications, will still be targetting a low end baseline architecture and therefore have a different outcome. I can say that in this space we are only now reaching the point where we can start compiling for AVX2, as we can expect the lowest end-user processor to support it.
by daemin - GCC already solved it: https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html The operations behave like C++ valarrays. Addition is defined as the addition of the corresponding elements of the operands. For example, in the code below, each of the 4 elements in a is added to the corresponding 4 elements in b and the resulting vector is stored in c.by countWSS
- Thanks!
- Those type attributes are also used for the x86 intrinsics API, and they override default C behaviors like promotions and presumptions around aliasing (ironically they make type punning easier, though maybe it was just the few use cases I explored, and this isn't an area where I have alot of experience). C23 also gained the _BitInt type, which discards all the old promotion rules, which should help autovectorization.
I think ISPC is still the proper way to go. But these days everybody wants One Language to Rule Them All along with standard libraries for doing everything out-of-the-box. And while in principle ISPC's approach could be stitched into C or C++ in a fairly clean manner (perhaps with well-defined and enforced segregation of constructs to minimize complexity), it's just not gonna happen: C++ is too enamored with constructing libraries through deeply complex templated types (hammer, nail, yada yada), and C is just too conservative (though if GCC or clang went the distance with a full implementation, there's a good chance the C committee would adopt it).
by wahern - And these are also available in clang. https://clang.llvm.org/docs/LanguageExtensions.html#vectors-...:
“Vectors and Extended Vectors
Supports the GCC, OpenCL, AltiVec, NEON, SVE and RVV vector extensions”
by Someone - "The Default Width Problem" -- this section seems confused and definitely reeks of LLM authorship. It's comparing -march=native against std::simd and complaining that std::simd<T,8> breaks portability with pre-Haswell. This is a real issue, but -march=native is no better! It bakes in the SIMD width at compile-time as well, so that binary also won't run on a pre-Haswell machine. It's a real issue but neither side solves it. You need runtime dispatch (a la Google Highway) to solve this.by StilesCrisis
- The linked[1] "six reasons to use std::simd" was just what I needed after a long week. Hilarious!by magicalhippo
- This is the first time I've seen a classic for loop called a "boomer loop", but apparently this isn't even the first instance (not the first definition):by Rendello
- It should have been "eight reasons to use std::simd". Inefficient.by boring-human
- isn't that just QoI issues? There's a reason why the libstdc++ folks labelled their implementation as experimental.by mgaunard
- That certainly convinced me. When I was doing my taxes recently and had to watch those forced loading animations, I kept asking myself "why can't my compiler do this?" Thanks to std::simd, now it can!
- I made the first proposal to the C++ standard committee to introduce SIMD in 2011, before Matthias Kretz got involved with his own version (which is what became std::simd). This was based on what eventually became Eve (mentioned in the article).
Back then, it was rejected, for the same arguments that people are making today, such as not mapping to SVE well, having a separate way to express control flow etc.
There was a real alternative being considered at the time: integrating ISPC-like semantics natively in the language. Then that died out (I'm not sure why), and SIMD became trendy, so the committee was more open to doing something to show that they were keeping up with the times.
by mgaunard - Trying to abstract over SVE with a SIMD library is a bit of a fool's errand. The intended programming model is just too different from traditional ISAs, and there are algorithms that are nearly impossible to write efficiently for it. All the ones I've seen wrap it up as a bastardized fixed length ISA, and even ARM's own guidance basically recommends that approach.
Frankly, the length agnostic stuff is a mistake that I hope hardware designers will eventually see the light on, like delay slots.
- To me it’s clear adding the ability to express intent to parallelise is the Right Thing. This is the only way the compiler can actually know what you want it to do.by rbanffy
- > There was a real alternative being considered at the time: integrating ISPC-like semantics natively in the language.
I think this is the best solution for truely portable SIMD. Sure it doesn't cover everything, but it makes autovec explicit, guaranteed and more powerfull.
One of the biggest problems with "portable" SIMD libraries, is that when it's used for simple things, often autovec is better, as it has access to the direct ISA semantics and can much easier do things like unrolling.
by camel-cdr - The point about the optimizer only seeing "opaque templates and function calls" makes little sense.
First off, templates are the opposite of opaque due to the fundamental requirement that the implementation be visible to every translation unit using a template. This makes any function calls trivially inlinable.
Second, and the reason for the above requirement, templates are compiled by monomorphization – making a distinct, separately optimizable copy of each concrete instantiation of a template. By the time the compiler backend sees the intermediate representation, there’s nothing about templates left.
There are of course reasons why highly abstracted template code may be difficult to optimize, for instance if function call chains are so deep that the inliner gives up. There are also legitimate reasons why a fully language-based solution might beat a library-based one. But one of the points of adding a library to the std is that the standard library is allowed to cheat as much as it wants. It can be deeply integrated to the compiler and implemented entirely using compiler magic if necessary.
std::simd may be too little, too late for many reasons, but I doubt any of them is that the compiler can’t see through the code.
by Sharlin