Skip to content

Commit e628a29

Browse files
Document Simd is Simd<Wrapping<T>, N>
and other quirks like panicking and the equivalence to zipping and mapping binary ops
1 parent 672bfeb commit e628a29

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

crates/core_simd/src/vector.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,39 @@ pub(crate) mod ptr;
1212
use crate::simd::intrinsics;
1313
use crate::simd::{LaneCount, Mask, MaskElement, SupportedLaneCount};
1414

15-
/// A SIMD vector of `LANES` elements of type `T`.
15+
/// A SIMD vector of `LANES` elements of type `T`. `Simd<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`.
16+
/// This type is commonly known by names like `f32x4` or `Vec4` in many programming languages.
17+
///
18+
/// Two vectors of the same type and length will, by convention, support the binary operations (+, *, etc.) that `T` does.
19+
/// These take the lanes at each index on the left-hand side and right-hand side, perform the binary operation,
20+
/// and return the result in the same lane in a vector of equal size. For a given operator, this is equivalent to zipping
21+
/// the two arrays together and mapping the operator over each lane.
22+
///
23+
/// ```rust
24+
/// # #![feature(array_zip, portable_simd)]
25+
/// # use core::simd::{Simd};
26+
/// let a0: [i32; 4] = [-2, 0, 2, 4];
27+
/// let a1 = [10, 9, 8, 7];
28+
/// let zm_add = a0.zip(a1).map(|(lhs, rhs)| lhs + rhs);
29+
/// let zm_mul = a0.zip(a1).map(|(lhs, rhs)| lhs * rhs);
30+
///
31+
/// // `Simd<T, N>` implements `From<[T; N]>
32+
/// let [v0, v1] = [a0, a1].map(|a| Simd::from(a));
33+
/// // Which means arrays implement `Into<Simd<T, N>>`.
34+
/// assert_eq!(v0 + v1, zm_add.into());
35+
/// assert_eq!(v0 * v1, zm_mul.into());
36+
/// ```
37+
///
38+
/// `Simd` with integers has the quirk that these operations are also inherently wrapping, as if `T` was [`Wrapping<T>`].
39+
/// Thus, `Simd` does not implement `wrapping_add`, because that is the behavior of the normal operation.
40+
/// This means there is no warning on overflows, even in "debug" builds.
41+
/// For most applications where `Simd` is appropriate, it is "not a bug" to wrap,
42+
/// and even "debug builds" are unlikely to tolerate the loss of performance.
43+
/// You may want to consider using explicitly checked arithmetic if such is required.
44+
/// Division by zero still causes a panic, so you may want to consider using floating point numbers if that is unacceptable.
45+
///
46+
/// [`Wrapping<T>`]: core::num::Wrapping
47+
///
1648
#[repr(simd)]
1749
pub struct Simd<T, const LANES: usize>([T; LANES])
1850
where

0 commit comments

Comments
 (0)