aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2013-08-05 14:17:49 -0400
committerErik Schnetter <schnetter@gmail.com>2013-08-05 14:17:49 -0400
commit8971b8ba5639d39a161d03bdd8c1e2643e5f0f37 (patch)
treecd525b95df6652f857fa1dc77e428fb97ebec651
parent7119df45e3bd7e7ad353719f7b41a71ebb604912 (diff)
CarpetLib: Use posix_memalign to allocate aligned memory
-rw-r--r--Carpet/CarpetLib/src/mem.cc92
1 files changed, 42 insertions, 50 deletions
diff --git a/Carpet/CarpetLib/src/mem.cc b/Carpet/CarpetLib/src/mem.cc
index c8bb8388b..1a529e08a 100644
--- a/Carpet/CarpetLib/src/mem.cc
+++ b/Carpet/CarpetLib/src/mem.cc
@@ -69,8 +69,6 @@ namespace {
assert(max_cache_linesize>0);
return max_cache_linesize;
}
-
- bool need_alignment = false;
}
@@ -91,12 +89,26 @@ mem (size_t const vectorlength, size_t const nelems,
{
DECLARE_CCTK_PARAMETERS;
if (memptr == NULL) {
- const double nbytes = vectorlength * nelems * sizeof (T);
- if (max_allowed_memory_MB > 0
- and (total_allocated_bytes + nbytes > MEGA * max_allowed_memory_MB))
+
+#if VECTORISE
+ size_t const vector_size = CCTK_REAL_VEC_SIZE;
+#else
+ size_t const vector_size = 1;
+#endif
+ size_t const final_padding = vector_size - 1;
+ size_t const max_cache_linesize = get_max_cache_linesize();
+ size_t const alignment =
+ align_up(max_cache_linesize, vector_size * sizeof (T));
+ assert(alignment >= 1);
+ // Safety check
+ assert(alignment <= 1024);
+
+ const double nbytes = (vectorlength * nelems + final_padding) * sizeof (T);
+ if (max_allowed_memory_MB > 0 and
+ (total_allocated_bytes + nbytes > MEGA * max_allowed_memory_MB))
{
T Tdummy;
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
"Refusing to allocate %.0f bytes (%.3f MB) of memory for type %s. %.0f bytes (%.3f MB) are currently allocated in %d objects. The parameter file specifies a maximum of %d MB",
double(nbytes), double(nbytes/MEGA),
typestring(Tdummy),
@@ -105,46 +117,12 @@ mem (size_t const vectorlength, size_t const nelems,
int(total_allocated_objects),
int(max_allowed_memory_MB));
}
- try {
- // TODO: use posix_memalign instead, if available
- size_t const max_cache_linesize = get_max_cache_linesize();
-#if VECTORISE
- size_t const vector_size = CCTK_REAL_VEC_SIZE * sizeof(T);
-#else
- size_t const vector_size = sizeof(T);
-#endif
- size_t const alignment = align_up(max_cache_linesize, vector_size);
- assert(alignment >= 1);
- // Safety check
- assert(alignment <= 1024);
- // Assume optimistically that operator new returns well-aligned
- // pointers
- if (not need_alignment) {
- // Operator new works fine; just call it
- storage_base_ = new T [vectorlength * nelems];
- need_alignment = size_t(storage_base_) & (alignment-1);
- if (need_alignment) {
- // This pointer is no good; try again with manual alignment
- delete [] storage_base_;
- CCTK_INFO("Switching memory allocation to manual alignment");
- goto allocate_with_alignment;
- }
- storage_ = storage_base_;
- } else {
- allocate_with_alignment:
- // Operator new needs manual alignment
- size_t const max_padding = div_up(alignment, sizeof(T));
- assert(ptrdiff_t(max_padding) >= 0);
- storage_base_ = new T [vectorlength * nelems + max_padding];
- storage_ = (T*) (size_t(storage_base_ + max_padding) & ~(alignment-1));
- assert(size_t(storage_) >= size_t(storage_base_ ) and
- size_t(storage_) <= size_t(storage_base_ + max_padding));
- }
- assert(not (size_t(storage_) & (alignment-1)));
- owns_storage_ = true;
- } catch (...) {
+
+ void* ptr;
+ const int ierr = posix_memalign(&ptr, alignment, nbytes);
+ if (ierr) {
T Tdummy;
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ CCTK_VError(__LINE__, __FILE__, CCTK_THORNSTRING,
"Failed to allocate %.0f bytes (%.3f MB) of memory for type %s. %.0f bytes (%.3f MB) are currently allocated in %d objects",
double(nbytes), double(nbytes/MEGA),
typestring(Tdummy),
@@ -152,13 +130,18 @@ mem (size_t const vectorlength, size_t const nelems,
double(total_allocated_bytes/MEGA),
int(total_allocated_objects));
}
+
+ storage_base_ = (T*)ptr;
+ storage_ = storage_base_;
+ assert(not (size_t(storage_) & (alignment-1)));
+ owns_storage_ = true;
+
total_allocated_bytes += nbytes;
max_allocated_bytes = max (max_allocated_bytes, total_allocated_bytes);
if (poison_new_memory) {
- memset (storage_base_,
- poison_value, (vectorlength * nelems +
- storage_ - storage_base_) * sizeof (T));
+ memset (storage_, poison_value, nbytes);
}
+
} else {
assert (memsize >= vectorlength * nelems * sizeof (T));
// Don't poison the memory. Passing in a pointer allows the
@@ -176,8 +159,17 @@ mem<T>::
{
assert (not has_clients());
if (owns_storage_) {
- delete [] storage_base_;
- const double nbytes = vectorlength_ * nelems_ * sizeof (T);
+ free(storage_base_);
+
+#if VECTORISE
+ size_t const vector_size = CCTK_REAL_VEC_SIZE;
+#else
+ size_t const vector_size = 1;
+#endif
+ size_t const final_padding = vector_size - 1;
+
+ const double nbytes =
+ (vectorlength_ * nelems_ + final_padding) * sizeof (T);
total_allocated_bytes -= nbytes;
}
-- total_allocated_objects;