Add vectorized integer division for int32 with AVX512, AVX or SSE.

This commit is contained in:
Rasmus Munk Larsen
2022-09-21 00:27:23 +00:00
parent 5ffe7b92e0
commit 7b2901e2aa
5 changed files with 80 additions and 8 deletions

View File

@@ -195,6 +195,7 @@ template<> struct packet_traits<int> : default_packet_traits
Vectorizable = 1,
AlignedOnScalar = 1,
HasCmp = 1,
HasDiv=1,
size=4,
HasShift = 1,
@@ -369,6 +370,22 @@ template<> EIGEN_STRONG_INLINE Packet16b pmul<Packet16b>(const Packet16b& a, con
template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_div_pd(a,b); }
template <>
EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& a,
const Packet4i& b) {
#ifdef EIGEN_VECTORIZE_AVX
return _mm256_cvttpd_epi32(
_mm256_div_pd(_mm256_cvtepi32_pd(a), _mm256_cvtepi32_pd(b)));
#else
__m128i q_lo = _mm_cvttpd_epi32(_mm_div_pd(_mm_cvtepi32_pd(a), _mm_cvtepi32_pd(b)));
__m128i q_hi =
_mm_cvttpd_epi32(_mm_div_pd(_mm_cvtepi32_pd(vec4i_swizzle1(a, 2, 3, 0, 1)),
_mm_cvtepi32_pd(vec4i_swizzle1(b, 2, 3, 0, 1))));
return vec4i_swizzle1(_mm_unpacklo_epi32(q_lo, q_hi), 0, 2, 1, 3);
#endif
}
// for some weird raisons, it has to be overloaded for packet of integers
template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); }
#ifdef EIGEN_VECTORIZE_FMA
@@ -1142,6 +1159,11 @@ template<> EIGEN_STRONG_INLINE bool predux_any(const Packet4f& x)
return _mm_movemask_ps(x) != 0x0;
}
template<> EIGEN_STRONG_INLINE bool predux_any(const Packet4i& x)
{
return _mm_movemask_ps(_mm_castsi128_ps(x)) != 0x0;
}
EIGEN_DEVICE_FUNC inline void
ptranspose(PacketBlock<Packet4f,4>& kernel) {
_MM_TRANSPOSE4_PS(kernel.packet[0], kernel.packet[1], kernel.packet[2], kernel.packet[3]);