Module slipstream::mask
source · Expand description
Bool-like types used for masked operations.
With multi-lane vectors, it is sometimes useful to do a lane-wise comparison or to disable some
of the lanes for a given operation. Naturally, one would express this using a correctly sized
bool
array.
Nevertheless, the CPU SIMD instructions don’t use bools, but signal true
/false
with a
full-sized type with either all bits set to 1 or 0 (TODO: this is not true for AVX-512, what do
we want to do about it?). Therefore, we define our own types that act like bools, but are
represented in the above way. The comparison operators return vectors of these base mask types.
The selection operations accept whatever mask vector with the same number of lanes, but they
are expected to act fastest with the correct sized ones.
For the purpose of input, bool
is also considered a mask type.
The interesting operations are:
The number in the type name specifies the number of bits. Therefore, for the
u16x4
, the natural mask type is a vector of 4 m16
, which is
m16x4
.
While it is possible to operate with the bools (by converting them), it is more common to simply pipe the masks back into the vectors. Note that they do implement the usual boolean operators (however, only the non-shortcircuiting/bitwise variants). These work lane-wise.
Examples
fn abs(vals: &mut [i32]) {
let zeroes = i32x8::default();
for mut v in vals.vectorize_pad(i32x8::default()) {
// Type of this one is m32x8 and is true whereever the lane isnegative.
let negative = v.lt(zeroes);
// Pick lanes from v where non-negative, pick from -v where negative.
*v = v.blend(-*v, negative);
}
}
let mut data = [1, -2, 3];
abs(&mut data);
assert_eq!(data, [1, 2, 3]);