Simplify cost computations based on HugeCost being smaller that unrolling limit

This commit is contained in:
Gael Guennebaud 2015-10-28 13:39:02 +01:00
parent 1f11dd6ced
commit 8531304858
7 changed files with 11 additions and 26 deletions

View File

@ -98,10 +98,8 @@ private:
enum { enum {
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
MayUnrollCompletely = int(Dst::SizeAtCompileTime) != Dynamic MayUnrollCompletely = int(Dst::SizeAtCompileTime) != Dynamic
&& int(SrcEvaluator::CoeffReadCost) < HugeCost
&& int(Dst::SizeAtCompileTime) * int(SrcEvaluator::CoeffReadCost) <= int(UnrollingLimit), && int(Dst::SizeAtCompileTime) * int(SrcEvaluator::CoeffReadCost) <= int(UnrollingLimit),
MayUnrollInner = int(InnerSize) != Dynamic MayUnrollInner = int(InnerSize) != Dynamic
&& int(SrcEvaluator::CoeffReadCost) < HugeCost
&& int(InnerSize) * int(SrcEvaluator::CoeffReadCost) <= int(UnrollingLimit) && int(InnerSize) * int(SrcEvaluator::CoeffReadCost) <= int(UnrollingLimit)
}; };

View File

@ -83,8 +83,6 @@ inline bool DenseBase<Derived>::all() const
typedef internal::evaluator<Derived> Evaluator; typedef internal::evaluator<Derived> Evaluator;
enum { enum {
unroll = SizeAtCompileTime != Dynamic unroll = SizeAtCompileTime != Dynamic
&& Evaluator::CoeffReadCost < HugeCost
&& NumTraits<Scalar>::AddCost < HugeCost
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
}; };
Evaluator evaluator(derived()); Evaluator evaluator(derived());
@ -109,8 +107,6 @@ inline bool DenseBase<Derived>::any() const
typedef internal::evaluator<Derived> Evaluator; typedef internal::evaluator<Derived> Evaluator;
enum { enum {
unroll = SizeAtCompileTime != Dynamic unroll = SizeAtCompileTime != Dynamic
&& Evaluator::CoeffReadCost < HugeCost
&& NumTraits<Scalar>::AddCost < HugeCost
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
}; };
Evaluator evaluator(derived()); Evaluator evaluator(derived());

View File

@ -455,7 +455,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost, + (InnerSize - 1) * NumTraits<Scalar>::AddCost,
Unroll = CoeffReadCost < HugeCost && CoeffReadCost <= EIGEN_UNROLLING_LIMIT, Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
LhsFlags = LhsEtorType::Flags, LhsFlags = LhsEtorType::Flags,
RhsFlags = RhsEtorType::Flags, RhsFlags = RhsEtorType::Flags,

View File

@ -50,20 +50,14 @@ public:
public: public:
enum { enum {
Cost = ( Derived::SizeAtCompileTime == Dynamic Cost = Derived::SizeAtCompileTime == Dynamic ? HugeCost
|| Derived::CoeffReadCost >= HugeCost : Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
|| (Derived::SizeAtCompileTime!=1 && functor_traits<Func>::Cost >= HugeCost)
) ? HugeCost
: Derived::SizeAtCompileTime * Derived::CoeffReadCost
+ (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
}; };
public: public:
enum { enum {
Unrolling = Cost < HugeCost && Cost <= UnrollingLimit Unrolling = Cost <= UnrollingLimit ? CompleteUnrolling : NoUnrolling
? CompleteUnrolling
: NoUnrolling
}; };
#ifdef EIGEN_DEBUG_ASSIGN #ifdef EIGEN_DEBUG_ASSIGN

View File

@ -109,14 +109,11 @@ void DenseBase<Derived>::visit(Visitor& visitor) const
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator; typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
ThisEvaluator thisEval(derived()); ThisEvaluator thisEval(derived());
enum { unroll = SizeAtCompileTime != Dynamic enum {
&& ThisEvaluator::CoeffReadCost < HugeCost unroll = SizeAtCompileTime != Dynamic
&& (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost < HugeCost) && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
&& SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost };
<= EIGEN_UNROLLING_LIMIT }; return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
return internal::visitor_impl<Visitor, ThisEvaluator,
unroll ? int(SizeAtCompileTime) : Dynamic
>::run(thisEval, visitor);
} }
namespace internal { namespace internal {

View File

@ -36,7 +36,7 @@ const int Infinity = -1;
* This value has to be positive to (1) simplify cost computation, and (2) allow to distinguish between a very expensive and very very expensive expressions. * This value has to be positive to (1) simplify cost computation, and (2) allow to distinguish between a very expensive and very very expensive expressions.
* It thus must also be large enough to make sure unrolling won't happen and that sub expressions will be evaluated, but not too large to avoid overflow. * It thus must also be large enough to make sure unrolling won't happen and that sub expressions will be evaluated, but not too large to avoid overflow.
*/ */
const int HugeCost = 1000; const int HugeCost = 10000;
/** \defgroup flags Flags /** \defgroup flags Flags
* \ingroup Core_Module * \ingroup Core_Module

View File

@ -204,6 +204,6 @@
// Check that a cost value is positive, and that is stay within a reasonable range // Check that a cost value is positive, and that is stay within a reasonable range
// TODO this check could be enabled for internal debugging only // TODO this check could be enabled for internal debugging only
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C) \ #define EIGEN_INTERNAL_CHECK_COST_VALUE(C) \
EIGEN_STATIC_ASSERT((C)>=0 && (C)<2*HugeCost*HugeCost, EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE); EIGEN_STATIC_ASSERT((C)>=0 && (C)<=HugeCost*HugeCost, EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE);
#endif // EIGEN_STATIC_ASSERT_H #endif // EIGEN_STATIC_ASSERT_H