For those unfamiliar, ultraviolet is a crate to do computer-graphics and games-related linear algebra, but fast, both in terms of productivity and in terms of runtime performance. In terms of productivity, ultraviolet uses no generics and is designed to be as straightforward of an interface as possible, resulting in fast compilation times and clear code. In addition, the lack of generics and Rust type-system "hacks" results in clear and concise errors that are easy to parse and fix for the user. In terms of runtime performance, ultraviolet was designed from the start with performance in mind. To do so, it provides two separate kinds of each type, one with usual scalar f32 values, and the other a 'wide' type which uses SIMD vector types for each value. Both kinds of each type provide essentially equivalent operations, while the wide types offer some functionality unique to them to facilitate performant SIMD algorithm design. This design is clearn and explicit in intent, and it also allows code to take full advantage of SIMD, offering the possibility of large performance gains for some workloads.
0.6 is the first major release since 0.4 several months ago; 0.5 was mostly incremental changes, though it did bring
serde support which was exciting.
The headlining features are
These are two features that have been at the top of 'the wishlist' for some time now, and I'm excited to finally land them! 256-bit/AVX support is particularly exciting for me, as some workloads that I'm interested in (namely rayn, my pathtracing renderer) should be able to get a fairly significant performance boost. In a test of purely the ray-sphere intersection test (which may be used in a renderer), you can see this starting to take shape (glam here is used to represent an optimized 'scalar' implementation, i.e. SIMD accelerated but horizontally rather than vertically as ultraviolet does):
glam (f32x1)- 917.0 us
ultraviolet_f32x4- 170.3 us
ultraviolet_f32x8- 100.9 us
Note: this isn't an apples-to-apples comparison... the algorithm needed to use the wide ultraviolet types is different than the standard one which may be used by scalar types like glam's. So while there is a lot of potential performance on the table, it's not "free".
Note 2: benchmarks performed on an i5 Mid-2014 Macbook Pro, and may vary significantly per processor/computer
In addition, there's been various other improvements, bug fixes, and enhancements, including significant performance improvements for Rotor-transform-vector operations. Here's the relevant benchmark:
glam- 6.4543 ns
ultraviolet0.5 - 7.4728 ns
ultraviolet0.6 - 6.1521 ns
This is an apples-to-apples comparison, all three just using standard scalar f32s, not wide-style SIMD types.
Finally, support for mint landed for most scalar types, which is great for interoperation between
ultraviolet and other Rust math crates, as well as making it easier to use
ultraviolet with ggez.
f64feature. Naming convention is
D[TypeName]for the f64 versions.
[TypeName]x4, allowing room for
mintfor scalar types
wgpu-specfic notes to
_wgputo some function names)
Rotor3::rotate_vecs()for improved performance on rotating multiple vecs with the same rotor
Into<Vec2; N> for Vec2xNimplementations
If you're interested, go check it out on crates.io, use it, and let me know if you have any issues or other feedback by visiting the GitHub issue tracker!