aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetLib
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2012-12-31 09:33:22 -0500
committerErik Schnetter <schnetter@gmail.com>2012-12-31 09:33:22 -0500
commit60c59fafbc23afa4ef175f624f0c310050271650 (patch)
tree89c50a9eb2d34e35a43cdabc57a5b4508aa669b1 /Carpet/CarpetLib
parentcdd5d0db583dbf1713822c06e8bd64b114b4564d (diff)
CarpetLib: Ensure allocated memory is aligned for vectorisation
Diffstat (limited to 'Carpet/CarpetLib')
-rw-r--r--Carpet/CarpetLib/src/mem.cc42
1 files changed, 38 insertions, 4 deletions
diff --git a/Carpet/CarpetLib/src/mem.cc b/Carpet/CarpetLib/src/mem.cc
index f3a4fa6ff..ab4bb1222 100644
--- a/Carpet/CarpetLib/src/mem.cc
+++ b/Carpet/CarpetLib/src/mem.cc
@@ -11,6 +11,8 @@
#include <sstream>
#include <string>
+#include <vectors.h>
+
#include "defs.hh"
#include "mem.hh"
@@ -68,10 +70,42 @@ mem (size_t const vectorlength, size_t const nelems,
int(max_allowed_memory_MB));
}
try {
- // TODO: align and pad storage
- size_t const padding = 0;
- storage_base_ = new T [vectorlength * nelems + padding];
- storage_ = storage_base_ + padding;
+ // TODO: use posix_memalign instead, if available
+ size_t const alignment = CCTK_REAL_VEC_SIZE * sizeof(T);
+ // Assume optimistically that operator new returns well-aligned
+ // pointers
+ static bool need_alignment = false;
+ 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 = CCTK_REAL_VEC_SIZE - 1;
+ storage_base_ = new T [vectorlength * nelems + max_padding];
+ storage_ = (T*) (size_t (storage_base_ + max_padding) & -alignment);
+#warning "TODO"
+ if (not (storage_ >= storage_base_ and
+ storage_ <= storage_base_ + max_padding)) {
+ cerr << "alignment=" << alignment << "\n"
+ << "max_padding=" << max_padding << "\n"
+ << "vectorlength=" << vectorlength << "\n"
+ << "nelems=" << nelems << "\n"
+ << "storage_base_=" << storage_base_ << "\n"
+ << "storage_=" << storage_ << "\n";
+ }
+ assert(storage_ >= storage_base_ and
+ storage_ <= storage_base_ + max_padding);
+ }
+ assert (not (size_t (storage_) & (alignment-1)));
owns_storage_ = true;
} catch (...) {
T Tdummy;