Skip to content

repr_c vs. repr_simd

Yoan edited this page Dec 25, 2017 · 1 revision

N.B: If you're on Stable or have disabled this crate's "repr_simd" feature, you don't need to worry about this.

The need for convenient SIMD-enabled types was a major motivation for creating vek. However, since there are a some inherent issues associated with Nightly Rust's #[repr(simd)], we would like to be able to also use regular #[repr(C)] vectors.

Therefore, vek splits relevant modules into two sub-modules, repr_c and repr_simd, hoping to make everyone happy. This is a trade-off involving functionality and implementation complexity that I am willing to make for now.

#[repr(simd)] caveats

You can instantiate any #[repr(simd)] type with any type as long as it is a "machine type", like f32 and i32, but not isize or newtypes.

Be careful: the size of a #[repr(simd)] vector is never guaranteed to be exactly equal that of the sum of its elements.
For instance, an SIMD Vec3<f32> actually contains 4 f32 elements on x86 instead of 3.
Also, repr_simd matrices are affected by this. You may check that elements of a matrix are tightly packed in memory with the is_packed() method.

Therefore, be extra careful when sending these as raw data, as you may want to do with OpenGL.

So, which do I pick?

Use types of repr_simd modules when:

  • You know how your target hardware handles #[repr(simd)], and therefore know how much memory SIMD vector structures actually take;
  • You don't mind alignment requirements and extra empty space;

Otherwise, or when in doubt, just pick repr_c. This crate always re-exports repr_c modules, so this would be the default.

Tips

One thing you could do is use renaming imports to convey your intent.

extern crate vek;

use vek::vec::repr_c::Vec4 as Vec4;
// If you're on Nightly...
use vek::vec::repr_simd::Vec4 as Simd4;

Or, if you know your target hardware...

extern crate vek;
#[macro_use]
extern crate cfg_if;

cfg_if! {
    // Just a quick example. We also may want to handle regular x86 with SSE enabled.
    if #[cfg(target_arch="x86-64")] {
        type Vec4f = vek::vec::repr_simd::Vec4<f32>;
    } else {
        type Vec4f = vek::vec::repr_c::Vec4<f32>;
    }
}

Also, repr_c and repr_simd vectors have From conversions for each other.

Clone this wiki locally