4 ms·
If you need performance, you must embrace vector nature of the hardware. Intel makes CPUs and invented many of these instructions sets, they also make a C++ co
by Const-me 7y ago
If you need performance, you must embrace vector nature of the hardware.
Intel makes CPUs and invented many of these instructions sets, they also make a C++ compiler, and their implementation of intrinsics is what's adopted by other compilers. They also provide decent documentation. Intel doesn't support any golang or rust packages or language extensions.
- adamnemecek 7y agoYou can use intrinsics from rust. You can use intrinsics from a lot of languages. https://github.com/AdamNiederer/faster https://github.com/AdamNiederer/faster In fact, in Rust, they are easier to use.
- Const-me 7y ago> You can use intrinsics from rust Right, I know there’s some support. > You can use intrinsics from a lot of languages. Yes. However, Intel (the guys making CPUs actually implementing these instructions) only supports them for C/C++. Just because you can use them from other languages (e.g. modern .NET has them as well, System.Numerics.Vectors) doesn’t necessarily mean it’s a good idea to do so. > In fact, in Rust, they are easier to use. That’s not “in fact”, that’s your opinion. Personally, I don’t think simple is good. When I code at that level of abstraction, I want to get whatever instructions are implemented by CPU. No more, no less. I’ve looked at example on the front page. There’re two methods to compute rsqrt in SSE/AVX, fast approximate one (rsqrtps), and precise one (sqrtps, divps). There’re several methods to compute ceil/floor, again with different tradeoffs. Do you know which instructions their example compile into? Neither do I. Also, one tricky part of CPU SIMD is cross-lane operations (shuffle, movelh/movehl, unpack, etc). Another one is integers: the instruction set is not comparable to any programming language, saturated versions of + and -, relatively high-level operations like psadbw, pmaddubsw, palignr, lack of something simple (e.g. can’t compare unsigned bytes for greater/less, only signed ones). For trivially simple algorithms that compute same math on wide vectors of float values, you better use OpenCL and run on GPU. Will likely be faster.
- adamnemecek 7y agoYou can link the exact same intrinsics in a rust binary to get the same intrinsics. > That’s not “in fact”, that’s your opinion. Personally, I don’t think simple is good. When I grow up I want to be as smart as you. And re: the faster project, you can use the exact same instructions. This is nothing about rust or not. Also, Rust is simply a better language for low level things even ignoring intrinsics.
- Const-me 7y ago> You can link the exact same intrinsics in a rust binary to get the same intrinsics. Intrinsics are not library functions. You don’t link them anywhere. They’re processed by compiler not linker, and for SIMD math, each one usually becomes a single instruction. Linked functions are too slow for that. > This is nothing about rust or not. When I code C and write y=_mm_rsqrt_ps(x) I know I’ll get my rsqrtps instruction. When I write y=_mm_div_ps(_mm_set1_ps(1), _mm_sqrt_ps(x)) I know I’ll get slower more precise version. I don’t want compiler to choose one for me while converting a formula into machine code.
- adamnemecek 7y agoOk not link but include header. You can do the same in rust. See the explicit section of the faster project.
- Const-me 7y ago> Ok not link but include header. Sorry to disappoint but Rust can’t include C++ headers. Even if it could, they wouldn’t work, because intrinsics are not library functions. > See the explicit section of the faster project. These aren’t C intrinsics, they are library functions exported from stdsimd crate. Which in turn forwards them to LLVM. Requires Rust nighty. Also I’m not sure that many levels of indirection are good for performance. You usually want these m128/m256 values to stay in registers. In C++, I sometimes have to write __forceinline to achieve that, or the compiler breaks performance by making function calls, or referencing RAM.
- steveklabnik 7y agoMy sibling already talked about the intrinsics, but I’d also like to point out that Intel does use Rust. https://github.com/intel/cloud-hypervisor https://github.com/intel/cloud-hypervisor for example. They also sponsor Rust conferences.
- Const-me 7y agoDoes Intel support Rust versions of their intrinsics? If no, how’s that relevant?
- adamnemecek 7y agoThey don't need to support it. It's the exact same linking process as from a c binary.
- steveklabnik 7y agoI’m not even sure what that would mean. A compiler is a compiler, regardless if it’s Intel making it or not. They’re the exact same thing as if you used clang. (It’s only relevant because you seem to imply that Intel doesn’t care about Rust at all. That’s not true.)
- Const-me 7y ago> They’re the exact same thing as if you used clang. Are you sure functions calls that crate adds on top of every single instruction, transmute(), as_i32x4(), etc., compile into nothing? And do so reliably i.e. every single time regardless on the surrounding code? BTW, functions built on top of intrinsics aren’t reliable in clang. I sometimes have to use compiler-specific trickery to force compilers to inline stuff, keep data in registers instead of loads/stores, and otherwise not screw up the performance.
- steveklabnik 7y agoIn my understanding, if it does not, that’s a bug. Compiler bugs do happen. Sounds like you’ve hit a few with clang.