Move max_align_t handling into jet.h This was currently buried in port.h. Since there is exactly one use of the max_align_t handling, it is better from a readability and cleanliness perspective to have this in jet.h. Change-Id: I2f3dde75df7c333bd95393b9e4fc4cd5160d6afb
diff --git a/include/ceres/internal/port.h b/include/ceres/internal/port.h index 9aa041a..d69d8c5 100644 --- a/include/ceres/internal/port.h +++ b/include/ceres/internal/port.h
@@ -32,8 +32,6 @@ #define CERES_PUBLIC_INTERNAL_PORT_H_ // This file needs to compile as c code. -#ifdef __cplusplus -#include <cstddef> #include "ceres/internal/config.h" #if defined(CERES_USE_OPENMP) @@ -56,33 +54,6 @@ # error One of CERES_USE_OPENMP, CERES_USE_TBB,CERES_USE_CXX11_THREADS or CERES_NO_THREADS must be defined. #endif -namespace ceres { - -// We allocate some Eigen objects on the stack and other places they -// might not be aligned to X(=16 [SSE], 32 [AVX] etc)-byte boundaries. If we -// have C++11, we can specify their alignment (which is desirable, as it means -// we can safely enable vectorisation on matrices). However, the standard gives -// wide lattitude as to what alignments are legal. It must be the case that -// alignments up to alignof(std::max_align_t) are valid, but this might be < 16 -// on some platforms, in which case even if using C++11, on these platforms -// we should not attempt to align to X-byte boundaries. If using < C++11, -// we cannot specify the alignment. -namespace port_constants { -static constexpr size_t kMaxAlignBytes = - // Work around a GCC 4.8 bug - // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019) where - // std::max_align_t is misplaced. -#if defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8 - alignof(::max_align_t); -#else - alignof(std::max_align_t); -#endif -} // namespace port_constants - -} // namespace ceres - -#endif // __cplusplus - // A macro to signal which functions and classes are exported when // building a DLL with MSVC. //
diff --git a/include/ceres/jet.h b/include/ceres/jet.h index 7eb199a..2106357 100644 --- a/include/ceres/jet.h +++ b/include/ceres/jet.h
@@ -258,21 +258,28 @@ // supported is < 16, in which case we do not specify an alignment, as this // implies the host is not a modern x86 machine. If using < C++11, we cannot // specify alignment. + #if defined(EIGEN_DONT_VECTORIZE) - // Without >= C++11, we cannot specify the alignment so fall back to safe, - // unvectorised version. Eigen::Matrix<T, N, 1, Eigen::DontAlign> v; #else // Enable vectorisation iff the maximum supported scalar alignment is >= // 16 bytes, as this is the minimum required by Eigen for any vectorisation. // // NOTE: It might be the case that we could get >= 16-byte alignment even if - // kMaxAlignBytes < 16. However we can't guarantee that this + // max_align_t < 16. However we can't guarantee that this // would happen (and it should not for any modern x86 machine) and if it // didn't, we could get misaligned Jets. static constexpr int kAlignOrNot = - 16 <= ::ceres::port_constants::kMaxAlignBytes - ? Eigen::AutoAlign : Eigen::DontAlign; + // Work around a GCC 4.8 bug + // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019) where + // std::max_align_t is misplaced. +#if defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8 + alignof(::max_align_t) >= 16 +#else + alignof(std::max_align_t) >= 16 +#endif + ? Eigen::AutoAlign : Eigen::DontAlign; + #if defined(EIGEN_MAX_ALIGN_BYTES) // Eigen >= 3.3 supports AVX & FMA instructions that require 32-byte alignment // (greater for AVX512). Rather than duplicating the detection logic, use @@ -287,11 +294,13 @@ // Eigen < 3.3 only supported 16-byte alignment. #define CERES_JET_ALIGN_BYTES 16 #endif + // Default to the native alignment if 16-byte alignment is not guaranteed to // be supported. We cannot use alignof(T) as if we do, GCC 4.8 complains that // the alignment 'is not an integer constant', although Clang accepts it. static constexpr size_t kAlignment = kAlignOrNot == Eigen::AutoAlign ? CERES_JET_ALIGN_BYTES : alignof(double); + #undef CERES_JET_ALIGN_BYTES alignas(kAlignment) Eigen::Matrix<T, N, 1, kAlignOrNot> v; #endif