28 #ifndef VC_COMMON_MEMORY_H_
29 #define VC_COMMON_MEMORY_H_
31 #include "memorybase.h"
36 #include <initializer_list>
37 #include "memoryfwd.h"
41 namespace Vc_VERSIONED_NAMESPACE
74 template<
typename T, Vc::MallocAlignment A>
77 return static_cast<T *
>(Common::malloc<A>(n *
sizeof(T)));
102 Vc_ALWAYS_INLINE
void free(T *p)
109 template<
typename V,
size_t Size>
struct _MemorySizeCalculation
111 enum AlignmentCalculations {
113 AlignmentMask = Alignment - 1,
114 MaskedSize = Size & AlignmentMask,
115 Padding = Alignment - MaskedSize,
116 PaddedSize = MaskedSize == 0 ? Size : Size + Padding
130 template <
typename V,
size_t Size1,
size_t Size2,
bool InitPadding>
131 #ifdef Vc_RECURSIVE_MEMORY
132 class Memory :
public MemoryBase<V, Memory<V, Size1, Size2, InitPadding>, 2,
133 Memory<V, Size2, 0, InitPadding>>
136 public MemoryBase<V, Memory<V, Size1, Size2, InitPadding>, 2,
137 Memory<V, Size2, 0, false>>
141 typedef typename V::EntryType EntryType;
144 #ifdef Vc_RECURSIVE_MEMORY
150 friend class MemoryBase<V, Memory<V, Size1, Size2, InitPadding>, 2, RowMemory>;
151 friend class MemoryDimensionBase<V, Memory<V, Size1, Size2, InitPadding>, 2,
155 PaddedSize2 = _MemorySizeCalculation<V, Size2>::PaddedSize
157 alignas(
static_cast<size_t>(Alignment))
160 #ifdef Vc_RECURSIVE_MEMORY
161 RowMemory m_mem[Size1];
163 EntryType m_mem[Size1][PaddedSize2];
170 VectorsCount = PaddedSize2 / V::Size
173 #ifdef Vc_RECURSIVE_MEMORY
180 for (
size_t i = 0; i < Size1; ++i) {
192 static constexpr
size_t rowsCount() {
return RowCount; }
207 static constexpr
size_t vectorsCount() {
return VectorsCount * Size1; }
218 template<
typename Parent,
typename RM>
221 Detail::copyVectors(*
this, rhs);
225 Vc_ALWAYS_INLINE Memory &operator=(
const Memory &rhs) {
226 Detail::copyVectors(*
this, rhs);
238 for (
size_t i = 0; i < vectorsCount(); ++i) {
288 template <
typename V,
size_t Size,
bool InitPadding>
290 #ifndef Vc_RECURSIVE_MEMORY
293 public MemoryBase<V, Memory<V, Size, 0u, InitPadding>, 1, void>
296 typedef typename V::EntryType EntryType;
299 friend class MemoryBase<V, Memory<V, Size, 0u, InitPadding>, 1, void>;
300 friend class MemoryDimensionBase<V, Memory<V, Size, 0u, InitPadding>, 1, void>;
303 MaskedSize = Size & (V::Size - 1),
305 Padding = V::Size - MaskedSize,
306 PaddedSize = MaskedSize == 0 ? Size : Size + Padding
308 alignas(
static_cast<size_t>(Alignment))
311 EntryType m_mem[PaddedSize];
317 VectorsCount = PaddedSize / V::Size
323 Base::lastVector() =
V::Zero();
327 Memory(std::initializer_list<EntryType> init)
329 Vc_ASSERT(init.size() <= Size);
330 Base::lastVector() =
V::Zero();
331 std::copy(init.begin(), init.end(), &m_mem[0]);
361 char *addr =
reinterpret_cast<char *
>(ptr);
363 addr -= Vc_OFFSETOF(MM, m_mem);
364 return *
new(addr) MM;
381 inline Memory(
const Memory &rhs)
383 Detail::copyVectors(*
this, rhs);
386 template <
size_t S>
inline Memory(
const Memory<V, S> &rhs)
388 assert(vectorsCount() == rhs.vectorsCount());
389 Detail::copyVectors(*
this, rhs);
392 inline Memory &operator=(
const Memory &rhs)
394 Detail::copyVectors(*
this, rhs);
398 template <
size_t S>
inline Memory &operator=(
const Memory<V, S> &rhs)
400 assert(vectorsCount() == rhs.vectorsCount());
401 Detail::copyVectors(*
this, rhs);
405 Vc_ALWAYS_INLINE Memory &operator=(
const EntryType *rhs) {
406 std::memcpy(m_mem, rhs, entriesCount() *
sizeof(EntryType));
409 inline Memory &operator=(
const V &v) {
410 for (
size_t i = 0; i < vectorsCount(); ++i) {
457 template<
typename V>
class Memory<V, 0u, 0u, true> :
public MemoryBase<V, Memory<V, 0u, 0u, true>, 1, void>
460 typedef typename V::EntryType EntryType;
463 friend class MemoryBase<V, Memory<V>, 1, void>;
464 friend class MemoryDimensionBase<V, Memory<V>, 1, void>;
465 enum InternalConstants {
467 AlignmentMask = Alignment - 1
469 size_t m_entriesCount;
470 size_t m_vectorsCount;
472 size_t calcPaddedEntriesCount(
size_t x)
474 size_t masked = x & AlignmentMask;
475 return (masked == 0 ? x : x + (Alignment - masked));
488 : m_entriesCount(size),
489 m_vectorsCount(calcPaddedEntriesCount(m_entriesCount)),
492 m_vectorsCount /= V::Size;
493 Base::lastVector() =
V::Zero();
503 template<
typename Parent,
typename RM>
505 : m_entriesCount(rhs.entriesCount()),
506 m_vectorsCount(rhs.vectorsCount()),
509 Detail::copyVectors(*
this, rhs);
519 Vc_ALWAYS_INLINE
Memory(
const Memory &rhs)
520 : m_entriesCount(rhs.entriesCount()),
521 m_vectorsCount(rhs.vectorsCount()),
524 Detail::copyVectors(*
this, rhs);
540 inline void swap(Memory &rhs) {
542 std::swap(m_entriesCount, rhs.m_entriesCount);
543 std::swap(m_vectorsCount, rhs.m_vectorsCount);
549 Vc_ALWAYS_INLINE Vc_PURE
size_t entriesCount()
const {
return m_entriesCount; }
554 Vc_ALWAYS_INLINE Vc_PURE
size_t vectorsCount()
const {
return m_vectorsCount; }
565 template<
typename Parent,
typename RM>
568 Detail::copyVectors(*
this, rhs);
572 Vc_ALWAYS_INLINE Memory &operator=(
const Memory &rhs) {
574 Detail::copyVectors(*
this, rhs);
587 Vc_ALWAYS_INLINE Memory &
operator=(
const EntryType *rhs) {
588 std::memcpy(m_mem, rhs, entriesCount() *
sizeof(EntryType));
671 using Common::Memory;
681 template<
typename V> Vc_ALWAYS_INLINE
void swap(Vc::Memory<V> &a, Vc::Memory<V> &b) { a.swap(b); }
684 #endif // VC_COMMON_MEMORY_H_
void free(T *p)
Frees memory that was allocated with Vc::malloc.
void prefetchClose(const void *addr)
Prefetch the cacheline containing addr to L1 cache.
Memory & operator=(const EntryType *rhs)
Overwrite all entries with the values stored in the memory at rhs.
void prefetchMid(const void *addr)
Prefetch the cacheline containing addr to L2 cache.
Memory(size_t size)
Allocate enough memory to access size values of type V::EntryType.
static constexpr size_t entriesCount()
size_t vectorsCount() const
void swap(Adapter< S, T, N > &a, std::size_t i, S &x)
Swaps one scalar object x with a SIMD slot at offset i in the simdized object a.
void prefetchForModify(const void *addr)
Prefetch the cacheline containing addr for modification.
static constexpr size_t vectorsCount()
A helper class for fixed-size two-dimensional arrays.
Memory(const MemoryBase< V, Parent, 1, RM > &rhs)
Copy the memory into a new memory area.
Memory & operator=(const MemoryBase< V, Parent, 1, RM > &rhs)
Overwrite all entries with the values stored in rhs.
Common interface to all Memory classes, independent of allocation on the stack or heap...
Common::AdaptSubscriptOperator< std::vector< T, Allocator >> vector
An adapted std::vector container with an additional subscript operator which implements gather and sc...
Helper class to ensure a given alignment.
Memory & operator=(const V &v)
Initialize all data with the given vector.
void prefetchForOneRead(const void *addr)
Prefetch the cacheline containing addr for a single read access.
size_t vectorsCount() const
void prefetchFar(const void *addr)
Prefetch the cacheline containing addr to L3 cache.
Memory(const Memory &rhs)
Overload of the above function.
size_t entriesCount() const
static constexpr size_t entriesCount()
T * malloc(size_t n)
Allocates memory on the Heap with alignment and padding suitable for vectorized access.
constexpr StreamingTag Streaming
Use this object for a flags parameter to request streaming loads and stores.
constexpr VectorSpecialInitializerZero Zero
The special object Vc::Zero can be used to construct Vector and Mask objects initialized to zero/fals...
Vector Classes Namespace.
void swap(Memory &rhs)
Swap the contents and size information of two Memory objects.
constexpr std::size_t MemoryAlignment
Specifies the most conservative memory alignment necessary for aligned loads and stores of Vector typ...
static Memory< V, Size, 0u, false > & fromRawData(EntryType *ptr)
Wrap existing data with the Memory convenience class.
static constexpr size_t vectorsCount()
Align on boundary of vector sizes (e.g.
static constexpr size_t rowsCount()
Memory & operator=(const MemoryBase< V, Parent, 2, RM > &rhs)
Copies the data from a different object.
~Memory()
Frees the memory which was allocated in the constructor.