Vc  1.0.0-dev
SIMD Vector Classes for C++
InterleavedMemoryWrapper< S, V > Class Template Reference

Detailed Description

template<typename S, typename V>
class Vc::Common::InterleavedMemoryWrapper< S, V >

Wraps a pointer to memory with convenience functions to access it via vectors.

Parameters
SThe type of the struct.
VThe type of the vector to be returned when read. This should reflect the type of the members inside the struct.
See also
operator[]

Definition at line 187 of file interleavedmemory.h.

#include <Vc/Memory>

Public Member Functions

 InterleavedMemoryWrapper (S *s)
 Constructs the wrapper object. More...
 
template<typename IT >
enable_if< std::is_convertible< IT, IndexType >::value &&!std::is_const< S >::value, Access > operator[] (IT indexes)
 Interleaved scatter/gather access. More...
 
ReadAccess operator[] (IndexType indexes) const
 const overload (gathers only) of the above function
 
ReadAccess gather (IndexType indexes) const
 alias of the above function
 
ReadSuccessiveEntries operator[] (size_t first) const
 Interleaved access. More...
 

Constructor & Destructor Documentation

InterleavedMemoryWrapper ( S *  s)
inline

Constructs the wrapper object.

Parameters
sA pointer to a C-array.

Definition at line 212 of file interleavedmemory.h.

Member Function Documentation

enable_if< std::is_convertible<IT, IndexType>::value && !std::is_const<S>::value, Access> operator[] ( IT  indexes)
inline

Interleaved scatter/gather access.

Assuming you have a struct of floats and a vector of 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.

Parameters
indexesVector of indexes that determine the gather locations.
Returns
A special (magic) object that executes the loads and deinterleave on assignment to a vector tuple.

Example:

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);
}

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 272 of file interleavedmemory.h.

ReadSuccessiveEntries operator[] ( size_t  first) const
inline

Interleaved access.

This function is an optimization of the function above, for cases where the index vector contains consecutive values. It will load V::Size consecutive entries from memory and deinterleave them into Vc vectors.

Parameters
firstThe first of V::Size indizes to be accessed.
Returns
A special (magic) object that executes the loads and deinterleave on assignment to a vector tuple.

Example:

struct Foo {
float x, y, z;
};
void foo(Foo *_data)
{
Vc::InterleavedMemoryWrapper<Foo, float_v> data(_data);
for (size_t i = 0; i < 32U; i += float_v::Size) {
float_v x, y, z;
(x, y, z) = data[i];
// now:
// x = { _data[i].x, _data[i + 1].x, _data[i + 2].x, ... }
// y = { _data[i].y, _data[i + 1].y, _data[i + 2].y, ... }
// z = { _data[i].z, _data[i + 1].z, _data[i + 2].z, ... }
...
}
}

Definition at line 319 of file interleavedmemory.h.


The documentation for this class was generated from the following file: