rustgd / cgmath

A linear algebra and mathematics library for computer graphics.

Home Page:https://docs.rs/cgmath

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Migrate to packed_simd

NNemec opened this issue · comments

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?

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

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.

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.

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