pub trait VecAlignment:
Seal
+ Sized
+ 'static
+ Send
+ Sync {
type InnerVector<const N: usize, T: Scalar>: Construct
where ScalarCount<N>: VecLen;
}Expand description
Sealed trait for the alignment rules of a vector.
- Doesn’t affect the outer vector API, just the inner implementation.
- Use the
Vec2,Vec3,Vec4type aliases for the default alignment.
Implemented by VecAligned and VecPacked, each have different uses and advantages.
To understand them first understand the Rust type-layout.
§VecPacked
ensures that the vector has the same type-layout as [T; N].
assert_eq!(
size_of::<Vector<N, T, VecPacked>>(),
size_of::<T>() * N
);
assert_eq!(
align_of::<Vector<N, T, VecPacked>>(),
align_of::<T>()
);§VecAligned
ensures that the vector is aligned to [T; N]’s size.
assert_eq!(
size_of::<Vector<N, T, VecAligned>>(),
(size_of::<T>() * N).next_power_of_two()
);
assert_eq!(
align_of::<Vector<N, T, VecAligned>>(),
(size_of::<T>() * N).next_power_of_two()
);-
This means that the size and alignment of
Vec3<T>is the same asVec4<T>’s. -
This means that
size/align_of<Vec2> = size_of<T> * 2, andsize/align_of<Vec3> = size/align_of<Vec4> = size_of<T> * 4.
§How to pick
Sometimes a specific type-layout is required.
For example GPU uniform-structs have strict type-layout requirements, which include vectors following the VecAligned type-layout.
When neither alignment is required, choose based on their performance advantages/disadvantages:
VecAlignedresults in faster computations because of SIMD registers which require the extra alignment.VecAlignedmay take more space because of the larger alignment, like whereVec3always takes the space of aVec4.VecPackedtakes less space because of the minimal alignment and the lack of padding.VecPackedmay result in slower computations because of the SIMD register’s requirements.
Basically only use VecPacked for vectors that you don’t perform much computation on.
On any other case use VecAligned.
Required Associated Types§
Sourcetype InnerVector<const N: usize, T: Scalar>: Construct
where
ScalarCount<N>: VecLen
type InnerVector<const N: usize, T: Scalar>: Construct where ScalarCount<N>: VecLen
Used by Vector to know its inner type.
In VecPacked: InnerVector = [T; N].
for a packed vector, the compiler knows that packed_vector.0 (the inner value) is always a [T; N].
in VecAligned: InnerVector = <ScalarCount<N> as VecLen>::InnerAlignedVector<T>.
for an aligned vector, the compiler doesn’t know the inner type unless N is known.
This is because Rust doesn’t have a single generic type capable of representing different sizes and alignments.
Basically Vector calls VecAlignment for its inner type,
which calls VecLen for the final result.
Why is the order Vector => VecAlignment => VecLen?
Why not Vector => VecLen => VecAlignment?
So that the compiler knows a packed vector is always an array.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.