3 ms·
I was curious about these libraries a few weeks ago and did some searching. Is there one that's got a clearly dominating set of users or contributors? I don't
by wyldfire 3y ago
I was curious about these libraries a few weeks ago and did some searching. Is there one that's got a clearly dominating set of users or contributors?
I don't know what a good way to compare these might be, other than perhaps activity/contributor count.
[1] https://github.com/simd-everywhere/simde https://github.com/simd-everywhere/simde
[2] https://github.com/ermig1979/Simd https://github.com/ermig1979/Simd
[3] https://github.com/google/highway https://github.com/google/highway
[4] https://gitlab.com/libeigen/eigen https://gitlab.com/libeigen/eigen
[5] https://github.com/shibatch/sleef https://github.com/shibatch/sleef
- Blackthorn 3y agoI'm not familiar with all of those but simde is afaict lower level than the others. It doesn't attempt to build any higher level abstractions, just translate between the existing standards and instruction sets.
- kolbe 3y agoThis entire space has a lot of options, and it's still an open question about what is the right approach. The fact is that C++ is a scalar language, with scalar guarantees and scalar assumptions built into their types. Hacking around this requires sacrifices, and different libraries are choosing different approaches. EVO (not featured in your list) is trying to approach it from an algorithms point of view. Highway is portable wrappers around common functionality. I think this is inherently a language-compiler problem. When libraries are using intrinsic functions to override compiler decisions, they interact poorly. One example: here's comparing a scalar versus an avx-512 intrinsic version of accumulate. https://godbolt.org/z/cMafh4Pnv https://godbolt.org/z/cMafh4Pnv IDK if you can read assembly, but the intrinsic version is waaaay worse, and about 4x slower. This is because using intrinsics makes it very hard for the compiler to do other optimizations it otherwise would (e.g. unrolling and reordering).
- deleted 3y ago[deleted]
- janwas 3y agoI agree compiler transforms sometimes do not interact well, but some still do help intrinsics. Interestingly, even `#pragma clang unroll(4)` is ignored here. Often in such cases we have to manually unroll, e.g. introduce multiple accumulators.
- janwas 3y agoI'm the main author of Highway, so I have some opinions :D Number of operations/platforms supported are important criteria. A hopefully unbiased commentary: Simde allows you to take existing nonportable intrinsics and get them to run on another platform. This is useful when you have a bunch of existing code and tight deadlines. The downside is less than optimal performance - a portable abstraction can be more efficient than forcing one platform to exactly match the semantics of another. Although a ton of effort has gone into Simde, sometimes it also resorts to autovectorization which may or may not work. Eigen and SLEEF are mostly math-focused projects that also have a portability layer. SLEEF is designed for C and thus has type suffixes which are rather verbose, see https://github.com/shibatch/sleef/blob/master/src/libm/sleefsimddp.c#L2305 https://github.com/shibatch/sleef/blob/master/src/libm/sleef... But it offers a complete (more so than Highway's) libm. Eigen is similarly useful for higher-level linear algebra that you probably do not want to reimplement yourself. However, I am skeptical of its expression template approach, in my experience one can run into trouble when the code gets complex (maybe some compiler limits are reached). Both of them may be less useful in non-math domains, AFAIK they lack many of the specialized instructions Highway has (e.g. interleaved load/store, compress/expand, software AES/CLMUL, popcount, lzcnt, saturated add/sub, 128-bit compare/minmax, fixed-point mul). I think Eigen would struggle with dynamic dispatch because of its header-only style, and SLEEF (understandably) lacks 8/16-bit types. Highway is used in multiple projects and because it is just a collection of wrapper functions around intrinsics, it is more predictable/reliable. For this reason it is also currently AFAIK the only solution that supports scalable vectors in SVE and RISC-V V. The main downside is that it requires C++11, and so we are unable to help projects that are C-only and cannot compile parts of their code as C++.