6 ms·
Expressive Vector Engine – SIMD in C++
- thrtythreeforty 2y agoThis library's eve::soa_vector is the first attempt I've seen at dealing with the "SOA problem," which is that if you write good, parallel-friendly code, all your types go to hell and never come back because the language can't express concepts like "my object is made from element 7 of each of these 6 pointers." Instead you write really FORTRAN-looking array processing code with no types or methods in sight. Does anyone know of other libraries that help a C++ programmer deal with struct-of-arrays?
- dyaroshev 2y agocppcast talked about soagen https://cppcast.com/soagen/ https://cppcast.com/soagen/ I didn't look into it too much.
- thrtythreeforty 2y agoThank you!
- vblanco 2y agoInteresting library, but i see it falls back into what happens to almost all SIMD libraries, which is that they hardcode the vector target completely and you cant mix/match feature levels within a build. The documentation recommends writing your kernels into DLLs and dynamic-loading them which is a huge mess https://jfalcou.github.io/eve/multiarch.html https://jfalcou.github.io/eve/multiarch.html Meanwhile xsimd (https://github.com/xtensor-stack/xsimd https://github.com/xtensor-stack/xsimd) has the feature level as a template parameter on its vector objects, which lets you branch at runtime between simd levels as you wish. I find its a far better way of doing things if you actually want to ship the simd code to users.
- spacechild1 2y agoThanks, that's an important caveat! > Meanwhile xsimd (https://github.com/xtensor-stack/xsimd https://github.com/xtensor-stack/xsimd) has the feature level as a template parameter on its vector objects That's pretty cool because you can write function templates and instantiate different versions that you can select at runtime.
- vblanco 2y agoYeah thts the fun of it, you create your kernel/function so that the simd level is a template parameter, and then you can use simple branching like: if(supports<avx512>){ myAlgo<avx512>(); } else{ myAlgo<avx>(); } Ive also used it for benchmarking to see if my code scales to different simd widths well and its a huge help
- dyaroshev 2y agoFYI: You don't want to do this. `supports<avx512>` is an expensive check. You really want to put this check in a static.
- spacechild1 2y agoI guess this was just pseudo-code. Of course you don't want to do a runtime feature check over and over again.
- kookamamie 2y ago100% agreed. This is the main reason ISPC is my go-to tool for explicit vectorization.
- janwas 2y ago+1, dynamic dispatch is important. Our Highway library has extensive support for this. Detailed intro by kfjahnke here: https://github.com/kfjahnke/zimt/blob/multi_isa/examples/multi_isa_example/multi_simd_isa.md https://github.com/kfjahnke/zimt/blob/multi_isa/examples/mul...
- nickpsecurity 2y agoI also found this looking for portable SIMD: https://github.com/google/highway https://github.com/google/highway
- shadowpho 2y agoWait what about AMD? They only claim support for intel and arm
- Conscat 2y agoEVE is personally my favorite SIMD library in any programming language. It's the only one I've tried that provides masked lane operations in a declarative style, aside from SPMD languages like CUDA or OpenMP. The [] syntax for that is admittedly pretty exotic C++, but I think the usefulness of the feature is worth it. I wish the documentation was better, though. When I first started, I struggled to figure out how to simply make a 4-lane float vector that I can pass into shaders, because almost all of the examples are written for the "wide" native-SIMD size.
- dyaroshev 2y agoHi! Thanks for your interest in the library. Here is a godbolt example: https://godbolt.org/z/bEGd7Tnb3 https://godbolt.org/z/bEGd7Tnb3 Here is a bunch of simple examples: https://github.com/jfalcou/eve/blob/fb093a0553d25bb8114f1396cced329ad99949f5/examples/start_here.cpp#L16 https://github.com/jfalcou/eve/blob/fb093a0553d25bb8114f1396... I personally think we have the following strenghs: * Algorithms. Writing SIMD loops is very hard. We give you a lot of ready to go loops. (find, search, remove, set_intersection to name a few). * zip and SOA support out of the box. * High quality codegen. I haven't seen other libraries care about unrolling/aligning data accesses - meanwhile these give you substantial improvements. * Supporting more than transform/reduce. We have really decent compress implemented for sse/avx/neon implemented for example. The following weaknesses: * We don't support runtime sized sve/rvv (only fixed size). We tried really hard, but unfortunately just the C++ language refuses to play ball there. Here is a discussion about that https://stackoverflow.com/questions/73210512/arm-sve-wrapping-runtime-sized-register https://stackoverflow.com/questions/73210512/arm-sve-wrappin... If this is something you need we recommend compiling a few dynamic libraries with the correct fixed lengths. Google Highway manage to pull it off but the trade off is a variadics interface that I personally find very difficult. * Runtime dispatch based on arch. We again recommend dlls for this. The problem here is ODR. I believe there is a solution based on preprocessor and namespaces I could use but it breaks as soon as modules become a thing. So - in the module world - we don't have an option. I'm happy for suggestions. * No MSVC support C++20 and MSVC is still not a thing enough. And each new version breaks something that was already working. Sad times. * Just tricky to get started. I don't know what to do about that. I'm happy to just write examples for people. If you wanna try a library - please create an issue/discussion or smth - I'm happy to take some time and try to solve your case. We talked about the library at CppCon: https://youtu.be/WZGNCPBMInI?si=buFteQB1e1vXRT5M https://youtu.be/WZGNCPBMInI?si=buFteQB1e1vXRT5M If you want to learn how SIMD algorithms work, here are a couple of talks I gave: https://youtu.be/PHZRTv3erlA?si=b87DBYMDskvzYcq1 https://youtu.be/PHZRTv3erlA?si=b87DBYMDskvzYcq1 https://youtu.be/vGcH40rkLdA?si=WL2e5gYQ7pSie9bd https://youtu.be/vGcH40rkLdA?si=WL2e5gYQ7pSie9bd Feel free to ask any questions.
- janwas 2y ago> Google Highway manage to pull it off but the trade off is a variadics interface that I personally find very difficult. I'm curious what you mean by 'variadics', and what exactly you find difficult? People new to Highway are often surprised by the d/tag argument to loads that say whether to load half/full vector, or no more than 4 elements, etc. The key is to understand these are just zero-sized structs used for type information, and are not the actual vector/data. After that, I observe introductory workshop participants are able to get started/productive quickly.