Skip to content
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

Migrate to packed_simd #490

Open
NNemec opened this issue Aug 24, 2019 · 4 comments
Open

Migrate to packed_simd #490

NNemec opened this issue Aug 24, 2019 · 4 comments

Comments

@NNemec
Copy link
Contributor

NNemec commented Aug 24, 2019

I found that cgmath has optional support for simd, which does not compile since Rust 1.33 and is deprecated in favor of packed_simd (see https://crates.io/crates/simd)

From what I can see, packed_simd is significantly different from simd, so migrating may be a tremendous effort. Has anyone looked into this? Is it feasible at all?

@Boscop
Copy link

Boscop commented May 29, 2020

Any update on this? :)
Or is there another crate that supports simd that is optimized for 4x4 matrices?

@NNemec
Copy link
Contributor Author

NNemec commented May 30, 2020

I did spend some more time on this last year, but got stuck on a fundamental problem and ultimately moved on to other projects:

The problem is that fully optimized SIMD code requires proper memory alignment of the data. For a vector4, this can be easily achieved with packed_simd. For the far more common vector3, one field has to be added for padding, affecting the data layout of cgmath in general. To make matters worse, the content of that additional field has to be considered carefully, because even if you never look at it, some operations are affected by it in their performance (e.g. when dividing by zero, handling denormals INF or NAN).

One approach would be to guarantee that the all safe operations make sure that the padding field is always zero and assume for their output and assume that it is zero on their input. For most operations, that is trivial. Some operations require a bit of extra code, but that is worth it for simplicity.

Another approach would be to make the extra field explicit in the API and give the user control and responsibility over what is stored in it.

Further problems are the handling of vector2 and vector1 - each of which has to be considered individually for SIMD, even though it is questionable how much effort this is worth at all.

So there are some questions to be answered and lots of work to do, but I still think it is a realistic and valuable endeavor. However, I am personally focused on other topics at the moment and have no idea when I might get back to this.

Last I looked, I could not find any Rust library offering comparable functionality to cgmath with reasonable SIMD support, but I would be quite interested to hear whether I missed anything or the situation has changed.

@aloucks
Copy link
Collaborator

aloucks commented May 31, 2020

There are a couple other math libraries with SIMD support:

https://github.com/termhn/ultraviolet
Ultraviolet's claim-to-fame is using "Structure of Arrays" (SoA) to gain a performance edge, but it may complicate your architecture (note the SoA types aren't mandatory). Ultraviolet seems quite experimental and lightly maintained. It uses rotors instead quaternions for rotation.

https://github.com/bitshifter/glam-rs
Glam seems to be a bit more popular and I believe it to be a solid choice. I think it's inspired by DirectXMath, but with a smaller API surface area.

https://github.com/aloucks/directx_math
I've also recently translated most of DirectXMath into a new crate. It's pure rust (i.e. not ffi bindings), but the API is as close to 1:1 with the c++ API as possible. This makes it feel a bit alien to use directly. I'm working on a wrapper crate to make it feel like idiomatic rust, but it's not published yet.

@NNemec
Copy link
Contributor Author

NNemec commented May 31, 2020

Thanks for the links!

I just had a brief look at these libraries:

  • The data layout of ultraviolet appears rather limiting to me. Instead of putting each geometrical vector into a SIMD vector on its own, it only offers handling four geometrical vectors at a time. That is excellent if your algorithm demands performing the same operations on multiple vectors, but in my experience that is rather rare for typical geometry codes.

  • glam and directx_math appear to offers proper SIMD with memory alignment as I had envisioned it when investigating the options for cgmath. Either of these should allow achieving optimal performance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants