template<typename V, size_t Size>
class Vc::Memory< V, Size, 0u >
A helper class to simplify usage of correctly aligned and padded memory, allowing both vector and scalar access.
Example:
int x = array[i];
array[i] = x;
}
int x = array.scalar(i);
array.scalar(i) = x;
}
}
This code allocates a small array and implements three equivalent loops (that do nothing useful). The loops show how scalar and vector read/write access is best implemented.
Since the size of 11 is not a multiple of int_v::Size (unless you use the scalar Vc implementation) the last write access of the vector loop would normally be out of bounds. But the Memory class automatically pads the memory such that the whole array can be accessed with correctly aligned memory addresses.
- Parameters
-
V | The vector type you want to operate on. (e.g. float_v or uint_v) |
Size | The number of entries of the scalar base type the memory should hold. This is thus the same number as you would use for a normal C array (e.g. float mem[11] becomes Memory<float_v, 11> mem). |
- See also
- Memory<V, 0u>
#include <Vc/Memory>
Inherits VectorAlignedBaseT< V >, and MemoryBase< V, Memory< V, Size, 0u >, 1, void >.
|
constexpr size_t | entriesCount () const |
|
constexpr size_t | vectorsCount () const |
|
Vc_PURE VectorPointerHelper< V, AlignedFlag > | vector (size_t i) |
|
Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > | vector (size_t i) const |
| Const overload of the above function. More...
|
|
Vc_PURE VectorPointerHelper< V, UnalignedFlag > | vector (size_t i, int shift) |
|
Vc_PURE const VectorPointerHelperConst< V, UnalignedFlag > | vector (size_t i, int shift) const |
| Const overload of the above function.
|
|
VectorPointerHelper< V, A > | vectorAt (size_t i, A align=Vc::Aligned) |
|
const VectorPointerHelperConst< V, A > | vectorAt (size_t i, A align=Vc::Aligned) const |
| Const overload of the above function. More...
|
|
Vc_PURE VectorPointerHelper< V, AlignedFlag > | firstVector () |
|
Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > | firstVector () const |
| Const overload of the above function.
|
|
Vc_PURE VectorPointerHelper< V, AlignedFlag > | lastVector () |
|
Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > | lastVector () const |
| Const overload of the above function.
|
|
static Memory<V, Size, 0u>& fromRawData |
( |
EntryType * |
ptr | ) |
|
|
static |
Wrap existing data with the Memory convenience class.
This function returns a reference to a Memory<V, Size, 0> object that you must capture to avoid a copy of the whole data:
Memory<float_v, 16> &m = Memory<float_v, 16>::fromRawData(someAlignedPointerToFloat)
- Parameters
-
ptr | An aligned pointer to memory of type V::EntryType (e.g. float for Vc::float_v). |
- Returns
- A Memory object placed at the given location in memory.
- Warning
- The pointer
ptr
passed to this function must be aligned according to the alignment restrictions of V
.
-
The size of the accessible memory must match
Size
. This includes the required padding at the end to allow the last entries to be accessed via vectors. If you know what you are doing you might violate this constraint.
-
It is your responsibility to ensure that the memory is released correctly (not too early/not leaked). This function simply adds convenience functions to access the memory.
constexpr size_t entriesCount |
( |
| ) |
const |
- Returns
- the number of scalar entries in the whole array.
- Note
- This function can be optimized into a compile-time constant.
constexpr size_t vectorsCount |
( |
| ) |
const |
- Returns
- the number of vectors in the whole array.
- Note
- This function can be optimized into a compile-time constant.
- Parameters
-
i | Selects the offset, where the vector should be read. |
- Returns
- a smart object to wrap the
i-th
vector in the memory.
The return value can be used as any other vector object. I.e. you can substitute something like
float_v a = ..., b = ...;
a += b;
with
This function ensures that only aligned loads and stores are used. Thus it only allows to access memory at fixed strides. If access to known offsets from the aligned vectors is needed the vector(size_t, int) function can be used.
Const overload of the above function.
- Parameters
-
i | Selects the offset, where the vector should be read. |
- Returns
- a smart object to wrap the
i-th
vector in the memory.
- Returns
- a smart object to wrap the
i-th
vector + shift
in the memory.
This function ensures that only unaligned loads and stores are used. It allows to access memory at any location aligned to the entry type.
- Parameters
-
i | Selects the memory location of the i-th vector. Thus if V::Size == 4 and i is set to 3 the base address for the load/store will be the 12th entry (same as &mem [12]). |
shift | Shifts the base address determined by parameter i by shift many entries. Thus vector(3, 1) for V::Size == 4 will load/store the 13th - 16th entries (same as &mem [13]). |
- Note
- Any shift value is allowed as long as you make sure it stays within bounds of the allocated memory. Shift values that are a multiple of
V::Size
will not result in aligned loads. You have to use the above vector(size_t) function for aligned loads instead.
-
Thus a simple way to access vectors randomly is to set
i
to 0 and use shift
as the parameter to select the memory address: mem.vector(i / V::Size, i % V::Size) += 1;
mem.vector(0, i) += 1;
- Returns
- a smart object to wrap the vector starting from the
i-th
scalar entry in the memory.
Example:
Memory<float_v, N> mem;
mem.setZero();
for (int i = 0; i < mem.entriesCount(); i += float_v::Size) {
mem.vectorAt(i) += b;
}
- Parameters
-
i | Specifies the scalar entry from where the vector will be loaded/stored. I.e. the values scalar(i), scalar(i + 1), ..., scalar(i + V::Size - 1) will be read/overwritten. |
align | You must take care to determine whether an unaligned load/store is required. Per default an aligned load/store is used. If i is not a multiple of V::Size you must pass Vc::Unaligned here. |
Const overload of the above function.
- Returns
- a smart object to wrap the vector starting from the
i-th
scalar entry in the memory.
- Parameters
-
i | Specifies the scalar entry from where the vector will be loaded/stored. I.e. the values scalar(i), scalar(i + 1), ..., scalar(i + V::Size - 1) will be read/overwritten. |
align | You must take care to determine whether an unaligned load/store is required. Per default an aligned load/store is used. If i is not a multiple of V::Size you must pass Vc::Unaligned here. |
- Returns
- the first vector in the allocated memory.
This function is simply a shorthand for vector(0).
- Returns
- the last vector in the allocated memory.
This function is simply a shorthand for vector(vectorsCount() - 1).