-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bit operations on float #388
Comments
Found another comment mentioning bit-ops for utility math: #109 (comment) |
In my opinion, It's certainly possible to write a newtype that implements the various bitops as well as |
It's certainly fair to model Let's begin with the raw case of C/C++ where we have A good example that has best of both worlds is C# (yes, I'm biased), which has good cross-platform intrinsics in the form of There is also a counter example from Zig, where Cross-platform intrinsics of C# and Zig compile down to slow scalar fallbacks in the semi-rare case of a missing instructions. AVX512 also introduces plenty of pretty niche float instructions that lack scalar equivalents, which could make any API on To finish off I would like to mention WebAssembly which should be familiar to Rust users. In WASM the SIMD intrinsics act on the general-purpose non-generic As mentioned in previous comments, bitwise operations for floats on |
I'm the owner of the SIMD types in .NET, so I'm also a bit biased here ;) We expose these bitwise operations on our Not only are these fundamental operations that have explicit instructions for both integers and floating-point vectors, but when considering SIMD or otherwise generic code they are core operations required across a wide range of scenarios. For example, with SIMD you typically want to avoid branching as much as possible (especially because any singular scalar branch is Given this is perf critical code and you're often wanting |
Notably, this does make it different from direct scalar code (given However, for our "generic math" feature we do actually allow this for scalar floats and so given This was again done for convenience and efficiency writing generic code. As an example, you frequently have the need to do bitwise manipulations or conditional checks, but may not know if doing an actual bitwise conversion to an associated integer type is efficient or you may even be in a language without associated types. Thus, by allowing generic code access to the operators you make it friendlier to end users and make it simpler for users to write functioning code. |
|
I would argue that WebAssembly has bitwise operations for integers, you just happen to also be able to use them on floats since they share the same In current Rust Portable SIMD, int<->float bitcasts usually also generate zero instructions, since the underlying SSE/AVX/AVX512/NEON/etc. registers are also identical, so no inter-register bitcasting move is needed. |
LLVM IR is the same way, it has no bitwise operations on vectors of floats, you have to bitcast to vectors of integers. Likewise, LLVM IR has separate better operations for those cases where bitwise operations are commonly used on floats: select, abs, copysign, negation, etc. |
Is there reason behind float SIMD not implementing bitwise operations?
I could not find much on this topic other than this comment.
This is severely annoying when it comes to porting algorithms that rely on bit manipulation of float values, like XOR for signs, or AND for masking off bits.
Is it because
Simd<f32, N>
is modelling thef32
primitive? Even then, I feel like this should be reconsidered. The workaround is messy (from_bits(lhs.to_bits() op rhs.to_bits())
) and writing generic code that uses bitwise operators is not feasible since you can't implement operators for external crates.The text was updated successfully, but these errors were encountered: