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)
   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)
   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));
   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...
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. 
Common::AdaptSubscriptOperator< std::vector< T, Allocator >> vector
An adapted std::vector container with an additional subscript operator which implements gather and sc...
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.