diff options
author | Gael Guennebaud <g.gael@free.fr> | 2015-03-13 21:15:50 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2015-03-13 21:15:50 +0100 |
commit | 1330f8bbd12306cc4955d943f27e5281d413bed4 (patch) | |
tree | 0296bc727247353a3032375cfca1af8499e91c36 /Eigen/src/Core/DenseStorage.h | |
parent | d99ab35f9e886a014be6d47606d232af1e668f76 (diff) |
bug #973, improve AVX support by enabling vectorization of Vector4i-like types, and enforcing alignement of Vector4f/Vector2d-like types to preserve compatibility with SSE and future Eigen versions that will vectorize them with AVX enabled.
Diffstat (limited to 'Eigen/src/Core/DenseStorage.h')
-rw-r--r-- | Eigen/src/Core/DenseStorage.h | 88 |
1 files changed, 83 insertions, 5 deletions
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h index 9186f59a7..522aaa299 100644 --- a/Eigen/src/Core/DenseStorage.h +++ b/Eigen/src/Core/DenseStorage.h @@ -34,14 +34,35 @@ void check_static_allocation_size() #endif } +template<typename T, int Size, typename Packet = typename packet_traits<T>::type, + bool Match = bool((Size%unpacket_traits<Packet>::size)==0), + bool TryHalf = bool(unpacket_traits<Packet>::size > Size) + && bool(unpacket_traits<Packet>::size > unpacket_traits<typename unpacket_traits<Packet>::half>::size) > +struct compute_default_alignment +{ + enum { value = 0 }; +}; + +template<typename T, int Size, typename Packet> +struct compute_default_alignment<T, Size, Packet, true, false> // Match +{ + enum { value = sizeof(T) * unpacket_traits<Packet>::size }; +}; + +template<typename T, int Size, typename Packet> +struct compute_default_alignment<T, Size, Packet, false, true> +{ + // current packet too large, try with an half-packet + enum { value = compute_default_alignment<T, Size, typename unpacket_traits<Packet>::half>::value }; +}; + /** \internal * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: * to 16 bytes boundary if the total size is a multiple of 16 bytes. */ template <typename T, int Size, int MatrixOrArrayOptions, int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0 - : (((Size*sizeof(T))%EIGEN_ALIGN_BYTES)==0) ? EIGEN_ALIGN_BYTES - : 0 > + : compute_default_alignment<T,Size>::value > struct plain_array { T array[Size]; @@ -81,14 +102,71 @@ struct plain_array #endif template <typename T, int Size, int MatrixOrArrayOptions> -struct plain_array<T, Size, MatrixOrArrayOptions, EIGEN_ALIGN_BYTES> +struct plain_array<T, Size, MatrixOrArrayOptions, 8> +{ + EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size]; + + EIGEN_DEVICE_FUNC + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7); + check_static_allocation_size<T,Size>(); + } + + EIGEN_DEVICE_FUNC + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size<T,Size>(); + } +}; + +template <typename T, int Size, int MatrixOrArrayOptions> +struct plain_array<T, Size, MatrixOrArrayOptions, 16> +{ + EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size]; + + EIGEN_DEVICE_FUNC + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15); + check_static_allocation_size<T,Size>(); + } + + EIGEN_DEVICE_FUNC + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size<T,Size>(); + } +}; + +template <typename T, int Size, int MatrixOrArrayOptions> +struct plain_array<T, Size, MatrixOrArrayOptions, 32> +{ + EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size]; + + EIGEN_DEVICE_FUNC + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31); + check_static_allocation_size<T,Size>(); + } + + EIGEN_DEVICE_FUNC + plain_array(constructor_without_unaligned_array_assert) + { + check_static_allocation_size<T,Size>(); + } +}; + +template <typename T, int Size, int MatrixOrArrayOptions> +struct plain_array<T, Size, MatrixOrArrayOptions, 64> { - EIGEN_USER_ALIGN_DEFAULT T array[Size]; + EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size]; EIGEN_DEVICE_FUNC plain_array() { - EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(EIGEN_ALIGN_BYTES-1); + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63); check_static_allocation_size<T,Size>(); } |