GemaCoreLib
The GeMA Core library
gmMemory.h
Go to the documentation of this file.
1 /************************************************************************
2 **
3 ** Copyright (C) 2014 by Carlos Augusto Teixera Mendes
4 ** All rights reserved.
5 **
6 ** This file is part of the "GeMA" software. It's use should respect
7 ** the terms in the license agreement that can be found together
8 ** with this source code.
9 ** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10 ** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11 ** A PARTICULAR PURPOSE.
12 **
13 ************************************************************************/
14 
25 #ifndef _GEMA_MEMORY_H_
26 #define _GEMA_MEMORY_H_
27 
28 #include "gmCoreConfig.h"
29 #include <assert.h>
30 
31 #include "gmOmp.h"
32 
33 
35 #define GM_CACHE_LINE_SIZE 64
36 
37 #ifdef Q_OS_WIN
38 
40 #define GM_CACHE_ALIGNED __declspec(align(GM_CACHE_LINE_SIZE))
41 
43 #define GmAlignedMalloc(size, align) _aligned_malloc((size), (align))
44 
46 #define GmAlignedFree(ptr) _aligned_free(ptr)
47 
48 #else
49 
50 #define GM_CACHE_ALIGNED __attribute__((aligned(GM_CACHE_LINE_SIZE)))
51 
52 inline void* GmAlignedMalloc(size_t size, size_t align)
53 {
54  void* ptr = NULL;
55  if(align < sizeof(void*)) // memalign requires a multiple of sizeof(void*)
56  align = sizeof(void*);
57  return posix_memalign(&ptr, align, size) ? NULL : ptr;
58 }
59 
60 #define GmAlignedFree(ptr) ::free(ptr)
61 
62 #endif
63 
65 inline void* GmAlignedMallocThrow(size_t size, size_t align)
66 {
67  void* p = GmAlignedMalloc(size, align);
68  if(p)
69  return p;
70  else
71  throw std::bad_alloc();
72 }
73 
75 inline bool GmMemoryIsAligned(void* ptr, int align)
76 {
77  return (((quintptr)ptr) & (align-1)) == 0;
78 }
79 
81 inline bool GmIsCacheAligned(void* ptr) { return GmMemoryIsAligned(ptr, GM_CACHE_LINE_SIZE); }
82 
90 template<class T> void GmConstructObjectsInMemory(T* ptr, int n = 1)
91 {
92  if(QTypeInfo<T>::isComplex) // Call default object constructor
93  {
94  for(int i = 0; i < n; i++, ptr++)
95  new (ptr) T();
96  }
97 }
98 
105 template<class T> void GmDestroyObjectsInMemory(T* ptr, int n = 1)
106 {
107  if(QTypeInfo<T>::isComplex) // Call object destructor
108  {
109  for(int i = 0; i < n; i++, ptr++)
110  ptr->~T();
111  }
112 }
113 
121 template<class T> void GmConstructAlignedObjectsInMemory(T* ptr, int align, int n)
122 {
123  assert(GmMemoryIsAligned(ptr, align));
124 
125  if(QTypeInfo<T>::isComplex) // Call default object constructor
126  {
127  int objectOffset = ceil(sizeof(T)/(double)align) * align;
128  for(int i = 0; i < n; i++)
129  {
130  new (ptr)T();
131  ptr = (T*)(((char*)ptr) + objectOffset);
132  }
133  }
134 }
135 
142 template<class T> void GmDestroyAlignedObjectsInMemory(T* ptr, int align, int n)
143 {
144  assert(GmMemoryIsAligned(ptr, align));
145 
146  if(QTypeInfo<T>::isComplex) // Call object destructor
147  {
148  int objectOffset = ceil(sizeof(T)/(double)align) * align;
149  for(int i = 0; i < n; i++)
150  {
151  ptr->~T();
152  ptr = (T*)(((char*)ptr) + objectOffset);
153  }
154  }
155 }
156 
167 inline void* GmPmemcpy(void* dst, const void* src, size_t n, int nt = 0,
168  size_t min = 10 * 1024 * 1024)
169 {
170 #ifdef _OPENMP
171  if(n < min)
172  return memcpy(dst, src, n);
173 
174  nt = GmOmpAdjustNumThreads(nt);
175 
176  // If n is < nt, it should also be less than min since our
177  // pre-condition states that min > maximum number of threads.
178  // This enables us to skip a test for adjusting nt if nt > n
179  assert(n >= nt);
180 
181  size_t bn = n / nt;
182  size_t ln = bn + n % nt; // The size of the last copy block
183 
184 #pragma omp parallel for num_threads(nt)
185  for(int i = 0; i < nt; i++)
186  memcpy(((char*)dst) + i * bn, ((const char*)src) + i * bn, i < nt - 1 ? bn : ln);
187 
188  return dst;
189 #else
190  Q_UNUSED(nt); Q_UNUSED(min);
191  return memcpy(dst, src, n);
192 #endif
193 }
194 
195 
196 
197 #ifdef ARMA_USE_GEMA_MEMORY_POOL
198 
199 GMC_API_EXPORT void* GmMemoryArmadilloPoolAlloc(size_t s);
200 GMC_API_EXPORT void GmMemoryArmadilloPoolFree (void* p);
201 
202 #endif
203 
204 #endif
205 
#define GM_CACHE_LINE_SIZE
Cache line size. TODO: Get this from a configuration parameter.
Definition: gmMemory.h:35
void * GmAlignedMallocThrow(size_t size, size_t align)
A version of GmAlignedMalloc that throws a bad_alloc exception on failure.
Definition: gmMemory.h:65
void * GmPmemcpy(void *dst, const void *src, size_t n, int nt=0, size_t min=10 *1024 *1024)
Parallel (thread enabled) version of memcpy using OpenMP.
Definition: gmMemory.h:167
Declaration of helper functions for using OpenMP that translate into "empty" statements if compiled w...
void GmConstructObjectsInMemory(T *ptr, int n=1)
Calls the default T constructor for creating 'n' consecutive objects in the memory area pointed by pt...
Definition: gmMemory.h:90
Declaration of usefull configuration definitions for the Core library.
void GmDestroyAlignedObjectsInMemory(T *ptr, int align, int n)
Calls T destructor for 'n' aligned objects in the memory area pointed by ptr.
Definition: gmMemory.h:142
bool GmIsCacheAligned(void *ptr)
Checks if a pointer is cache aligned or not.
Definition: gmMemory.h:81
int GmOmpAdjustNumThreads(int nt)
Adjusts the given number of threads. If nt <= 0 or if nt > maximum number of omp threads,...
Definition: gmOmp.h:51
bool GmMemoryIsAligned(void *ptr, int align)
Checks if a pointer is aligned to the given align (which must be a power of two)
Definition: gmMemory.h:75
#define GMC_API_EXPORT
Macro for controling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_LI...
Definition: gmCoreConfig.h:35
void GmDestroyObjectsInMemory(T *ptr, int n=1)
Calls T destructor for 'n' consecutive objects in the memory area pointed by ptr.
Definition: gmMemory.h:105
void GmConstructAlignedObjectsInMemory(T *ptr, int align, int n)
Calls the default T constructor for creating 'n' aligned objects in the memory area pointed by ptr.
Definition: gmMemory.h:121