Started to model the cost of divisions more accurately.

This commit is contained in:
Benoit Steiner 2016-03-25 11:02:56 -07:00
parent a86c9f037b
commit d94f6ba965
2 changed files with 28 additions and 1 deletions

View File

@ -60,6 +60,23 @@ template<typename T> struct GenericNumTraits
MulCost = 1
};
// Division is messy but important, because it is expensive and throughput
// varies significantly. The following numbers are based on min division
// throughput on Haswell.
template<bool Vectorized>
struct Div {
enum {
#ifdef EIGEN_VECTORIZE_AVX
AVX = true,
#else
AVX = false,
#endif
Cost = IsInteger ? (sizeof(T) == 8 ? (IsSigned ? 24 : 21) : (IsSigned ? 8 : 9)):
Vectorized ? (sizeof(T) == 8 ? (AVX ? 16 : 8) : (AVX ? 14 : 7)) : 8
};
};
typedef T Real;
typedef typename internal::conditional<
IsInteger,

View File

@ -238,7 +238,13 @@ template<typename Scalar> struct scalar_hypot_op {
};
template<typename Scalar>
struct functor_traits<scalar_hypot_op<Scalar> > {
enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
enum
{
Cost = 3 * NumTraits<Scalar>::AddCost +
2 * NumTraits<Scalar>::MulCost +
2 * NumTraits<Scalar>::template Div<false>::Cost,
PacketAccess = false
};
};
/** \internal
@ -564,6 +570,10 @@ struct scalar_inverse_mult_op {
{ return internal::pdiv(pset1<Packet>(m_other),a); }
Scalar m_other;
};
template<typename Scalar>
struct functor_traits<scalar_inverse_mult_op<Scalar> >
{ enum { PacketAccess = packet_traits<Scalar>::HasDiv, Cost = NumTraits<Scalar>::template Div<PacketAccess>::Cost }; };
} // end namespace internal