Interleaved scatter/gather access.
Assuming you have a struct of floats and a vector of \p indexes into the array, this function
can be used to access the struct entries as vectors using the minimal number of store or load
instructions.
\param indexes Vector of indexes that determine the gather locations.
\return A special (magic) object that executes the loads and deinterleave on assignment to a
vector tuple.
Example:
\code
struct Foo {
float x, y, z;
};
void fillWithBar(Foo *_data, uint_v indexes)
{
Vc::InterleavedMemoryWrapper<Foo, float_v> data(_data);
const float_v x = bar(1);
const float_v y = bar(2);
const float_v z = bar(3);
data[indexes] = (x, y, z);
// it's also possible to just store a subset at the front of the struct:
data[indexes] = (x, y);
// if you want to store a single entry, use scatter:
z.scatter(_data, &Foo::x, indexes);
}
float_v normalizeStuff(Foo *_data, uint_v indexes)
{
Vc::InterleavedMemoryWrapper<Foo, float_v> data(_data);
float_v x, y, z;
(x, y, z) = data[indexes];
// it is also possible to just load a subset from the front of the struct:
// (x, y) = data[indexes];
return Vc::sqrt(x * x + y * y + z * z);
}
\endcode
You may think of the gather operation (or scatter as the inverse) like this:
Memory: {x0 y0 z0 x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5 x6 y6 z6 x7 y7 z7 x8 y8 z8}
indexes: [5, 0, 1, 7]
Result in (x, y, z): ({x5 x0 x1 x7}, {y5 y0 y1 y7}, {z5 z0 z1 z7})
\warning If \p indexes contains non-unique entries on scatter, the result is undefined. If
\c NDEBUG is not defined the implementation will assert that the \p indexes entries are unique.
Definition at line 269 of file interleavedmemory.h.