GemaCoreLib
The GeMA Core library
Loading...
Searching...
No Matches
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
52inline 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
65inline 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
75inline bool GmMemoryIsAligned(void* ptr, int align)
76{
77 return (((quintptr)ptr) & (align-1)) == 0;
78}
79
81inline bool GmIsCacheAligned(void* ptr) { return GmMemoryIsAligned(ptr, GM_CACHE_LINE_SIZE); }
82
90template<class T> void GmConstructObjectsInMemory(T* ptr, int n = 1)
91{
92 if constexpr(QTypeInfo<T>::isComplex) // Call default object constructor
93 {
94 for(int i = 0; i < n; i++, ptr++)
95 new (ptr) T();
96 }
97 else
98 {
99 Q_UNUSED(ptr); Q_UNUSED(n);
100 }
101}
102
109template<class T> void GmDestroyObjectsInMemory(T* ptr, int n = 1)
110{
111 if constexpr(QTypeInfo<T>::isComplex) // Call object destructor
112 {
113 for(int i = 0; i < n; i++, ptr++)
114 ptr->~T();
115 }
116 else
117 {
118 Q_UNUSED(ptr); Q_UNUSED(n);
119 }
120}
121
129template<class T> void GmConstructAlignedObjectsInMemory(T* ptr, int align, int n)
130{
131 assert(GmMemoryIsAligned(ptr, align));
132
133 if constexpr(QTypeInfo<T>::isComplex) // Call default object constructor
134 {
135 int objectOffset = ceil(sizeof(T)/(double)align) * align;
136 for(int i = 0; i < n; i++)
137 {
138 new (ptr)T();
139 ptr = (T*)(((char*)ptr) + objectOffset);
140 }
141 }
142 else
143 {
144 Q_UNUSED(ptr); Q_UNUSED(align); Q_UNUSED(n);
145 }
146}
147
154template<class T> void GmDestroyAlignedObjectsInMemory(T* ptr, int align, int n)
155{
156 assert(GmMemoryIsAligned(ptr, align));
157
158 if constexpr(QTypeInfo<T>::isComplex) // Call object destructor
159 {
160 int objectOffset = ceil(sizeof(T)/(double)align) * align;
161 for(int i = 0; i < n; i++)
162 {
163 ptr->~T();
164 ptr = (T*)(((char*)ptr) + objectOffset);
165 }
166 }
167 else
168 {
169 Q_UNUSED(ptr); Q_UNUSED(align); Q_UNUSED(n);
170 }
171}
172
183inline void* GmPmemcpy(void* dst, const void* src, size_t n, int nt = 0,
184 size_t min = 10 * 1024 * 1024)
185{
186#ifdef _OPENMP
187 if(n < min)
188 return memcpy(dst, src, n);
189
190 nt = GmOmpAdjustNumThreads(nt);
191
192 // If n is < nt, it should also be less than min since our
193 // pre-condition states that min > maximum number of threads.
194 // This enables us to skip a test for adjusting nt if nt > n
195 assert(n >= nt);
196
197 size_t bn = n / nt;
198 size_t ln = bn + n % nt; // The size of the last copy block
199
200#pragma omp parallel for num_threads(nt)
201 for(int i = 0; i < nt; i++)
202 memcpy(((char*)dst) + i * bn, ((const char*)src) + i * bn, i < nt - 1 ? bn : ln);
203
204 return dst;
205#else
206 Q_UNUSED(nt); Q_UNUSED(min);
207 return memcpy(dst, src, n);
208#endif
209}
210
211
212
213#ifdef ARMA_USE_GEMA_MEMORY_POOL
214
215GMC_API_EXPORT void* GmMemoryArmadilloPoolAlloc(size_t s);
216GMC_API_EXPORT void GmMemoryArmadilloPoolFree (void* p);
217
218#endif
219
220#endif
221
Declaration of useful configuration definitions for the Core library.
#define GMC_API_EXPORT
Macro for controlling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_L...
Definition gmCoreConfig.h:35
#define GM_CACHE_LINE_SIZE
Cache line size. TODO: Get this from a configuration parameter.
Definition gmMemory.h:35
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:154
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
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:129
bool GmIsCacheAligned(void *ptr)
Checks if a pointer is cache aligned or not.
Definition gmMemory.h:81
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:183
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
void GmDestroyObjectsInMemory(T *ptr, int n=1)
Calls T destructor for 'n' consecutive objects in the memory area pointed by ptr.
Definition gmMemory.h:109
Declaration of helper functions for using OpenMP that translate into "empty" statements if compiled w...
int GmOmpAdjustNumThreads(int nt)
Adjusts the given number of threads. If nt <= 0 or if nt > maximum number of omp threads,...
Definition gmOmp.h:53