From: Wolfgang Bangerth Date: Wed, 15 Apr 2015 18:32:46 +0000 (-0500) Subject: Avoid the use of _mm_malloc/_mm_free in favor of posix_memalign. X-Git-Tag: v8.3.0-rc1~248^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F831%2Fhead;p=dealii.git Avoid the use of _mm_malloc/_mm_free in favor of posix_memalign. This has the additional advantage that free() can be used and we don't have to be special on both sides of memory allocation/deallocation. --- diff --git a/doc/news/changes.h b/doc/news/changes.h index d3ef58962d..3590125d3f 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -352,6 +352,16 @@ inconvenience this causes.
    +
  1. Fixed: There were a number of places in the library where we unconditionally + called functions _mm_malloc()/_mm_free() to allocate and free + memory with a known alignment. This function, however, is only available on + systems with x86 or x64_64 compatible processors. These places have now been + replaced by calling posix_memalign() instead, a function that + should be more widely available. +
    + (Wolfgang Bangerth, 2015/04/15) +
  2. +
  3. Deprecated: The library uses functions such as CellAccessor::subdomain_id(), TriaAccessor::manifold_id(), etc, but used the deviant spelling TriaAccessor::boundary_indicator(), TriaAccessor::set_boundary_indicator(), diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index 534510b3b7..ed1dcc97bd 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2011 - 2014 by the deal.II authors +// Copyright (C) 2011 - 2015 by the deal.II authors // // This file is part of the deal.II library. // @@ -21,16 +21,13 @@ #include #include #include +#include #include #include #include #include -#if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0 -#include -#endif - DEAL_II_NAMESPACE_OPEN @@ -538,16 +535,10 @@ AlignedVector::reserve (const size_type size_alloc) const size_type size_actual_allocate = new_size * sizeof(T); -#if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0 - // allocate and align along 64-byte boundaries (this is enough for all // levels of vectorization currently supported by deal.II) - T *new_data = static_cast(_mm_malloc (size_actual_allocate, 64)); -#else - T *new_data = static_cast(malloc (size_actual_allocate)); -#endif - if (new_data == 0) - throw std::bad_alloc(); + T *new_data; + Utilities::System::posix_memalign ((void **)&new_data, 64, size_actual_allocate); // copy data in case there was some content before and release the old // memory with the function corresponding to the one used for allocating @@ -558,11 +549,7 @@ AlignedVector::reserve (const size_type size_alloc) { dealii::internal::AlignedVectorMove(new_data, new_data + old_size, _data); -#if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0 - _mm_free(new_data); -#else free(new_data); -#endif } } else if (size_alloc == 0) @@ -582,11 +569,7 @@ AlignedVector::clear () while (_end_data != _data) (--_end_data)->~T(); -#if DEAL_II_COMPILER_VECTORIZATION_LEVEL > 0 - _mm_free(_data); -#else free(_data); -#endif } _data = 0; _end_data = 0; diff --git a/include/deal.II/base/utilities.h b/include/deal.II/base/utilities.h index 7a45c412da..4200224e60 100644 --- a/include/deal.II/base/utilities.h +++ b/include/deal.II/base/utilities.h @@ -375,6 +375,22 @@ namespace Utilities */ std::string get_time (); + /** + * Call the system function posix_memalign, or a replacement function if not + * available, to allocate memory with a certain minimal alignment. The + * first argument will then return a pointer to this memory block that can + * be released later on through a standard free call. + * + * @param memptr The address of a pointer variable that will after this call + * point to the allocated memory. + * @param alignment The minimal alignment of the memory block, in bytes. + * @param size The size of the memory block to be allocated, in bytes. + * + * @note This function checks internally for error codes, rather than + * leaving this task to the calling site. + */ + void posix_memalign (void **memptr, size_t alignment, size_t size); + /** * @deprecated Use Utilities::MPI::job_supports_mpi() instead. */ diff --git a/include/deal.II/lac/parallel_vector.templates.h b/include/deal.II/lac/parallel_vector.templates.h index eb3495e21f..1511dd8985 100644 --- a/include/deal.II/lac/parallel_vector.templates.h +++ b/include/deal.II/lac/parallel_vector.templates.h @@ -24,10 +24,6 @@ #include #include -#ifndef _MSC_VER -# include -#endif - DEAL_II_NAMESPACE_OPEN @@ -61,14 +57,16 @@ namespace parallel Assert (((allocated_size > 0 && val != 0) || val == 0), ExcInternalError()); if (val != 0) - _mm_free(val); - val = static_cast(_mm_malloc (sizeof(Number)*new_alloc_size, 64)); + free(val); + + Utilities::System::posix_memalign ((void **)&val, 64, sizeof(Number)*new_alloc_size); + allocated_size = new_alloc_size; } else if (new_alloc_size == 0) { if (val != 0) - _mm_free(val); + free(val); val = 0; allocated_size = 0; } diff --git a/include/deal.II/lac/vector.templates.h b/include/deal.II/lac/vector.templates.h index bcfe8b6190..eef2276507 100644 --- a/include/deal.II/lac/vector.templates.h +++ b/include/deal.II/lac/vector.templates.h @@ -42,14 +42,9 @@ #include #include -#ifndef _MSC_VER -# include -#endif - DEAL_II_NAMESPACE_OPEN - namespace internal { typedef types::global_dof_index size_type; @@ -2050,8 +2045,9 @@ Vector::allocate() { // make sure that we don't create a memory leak Assert (val == 0, ExcInternalError()); - val = static_cast(_mm_malloc (sizeof(Number)*max_vec_size, 64)); - Assert (val != 0, ExcOutOfMemory()); + + // then allocate memory with the proper alignment requirements of 64 bytes + Utilities::System::posix_memalign ((void **)&val, 64, sizeof(Number)*max_vec_size); } @@ -2060,7 +2056,7 @@ template void Vector::deallocate() { - _mm_free(val); + free(val); val = 0; } diff --git a/source/base/utilities.cc b/source/base/utilities.cc index 579a725049..e3d872b5b6 100644 --- a/source/base/utilities.cc +++ b/source/base/utilities.cc @@ -33,6 +33,10 @@ #include #include +#ifndef DEAL_II_MSVC +# include +#endif + #ifdef DEAL_II_MSVC # include #endif @@ -628,6 +632,23 @@ namespace Utilities } + void posix_memalign (void **memptr, size_t alignment, size_t size) + { +#ifndef DEAL_II_MSVC + const int ierr = ::posix_memalign (memptr, alignment, size); + + AssertThrow (ierr == 0, ExcOutOfMemory()); + AssertThrow (*memptr != 0, ExcOutOfMemory()); +#else + // Windows does not appear to have posix_memalign. just use the + // regular malloc in that case + *memptr = malloc (size); + AssertThrow (*memptr != 0, ExcOutOfMemory()); +#endif + } + + + bool job_supports_mpi () { return Utilities::MPI::job_supports_mpi();