fix big bug in loop unrolling

This commit is contained in:
Benoit Jacob 2007-10-10 06:33:09 +00:00
parent 06e1e0d83b
commit 3c98677376
3 changed files with 14 additions and 27 deletions

View File

@ -32,12 +32,12 @@ struct EiDotUnroller
static void run(const Derived1 &v1, const Derived2& v2, typename Derived1::Scalar &dot)
{
EiDotUnroller<Index-1, Size, Derived1, Derived2>::run(v1, v2, dot);
dot += v1[Index-1] * EiConj(v2[Index-1]);
dot += v1[Index] * EiConj(v2[Index]);
}
};
template<int Size, typename Derived1, typename Derived2>
struct EiDotUnroller<1, Size, Derived1, Derived2>
struct EiDotUnroller<0, Size, Derived1, Derived2>
{
static void run(const Derived1 &v1, const Derived2& v2, typename Derived1::Scalar &dot)
{
@ -45,8 +45,8 @@ struct EiDotUnroller<1, Size, Derived1, Derived2>
}
};
template<int Size, typename Derived1, typename Derived2>
struct EiDotUnroller<EiDynamic, Size, Derived1, Derived2>
template<int Index, typename Derived1, typename Derived2>
struct EiDotUnroller<Index, EiDynamic, Derived1, Derived2>
{
static void run(const Derived1 &v1, const Derived2& v2, typename Derived1::Scalar &dot)
{
@ -63,7 +63,7 @@ Scalar EiObject<Scalar, Derived>::dot(const OtherDerived& other) const
assert(IsVector && OtherDerived::IsVector && size() == other.size());
Scalar res;
if(SizeAtCompileTime != EiDynamic && SizeAtCompileTime <= 16)
EiDotUnroller<SizeAtCompileTime, SizeAtCompileTime, Derived, OtherDerived>
EiDotUnroller<SizeAtCompileTime-1, SizeAtCompileTime, Derived, OtherDerived>
::run(*static_cast<const Derived*>(this), other, res);
else
{

View File

@ -111,12 +111,8 @@ struct EiMatrixProductUnroller
static void run(int row, int col, const Lhs& lhs, const Rhs& rhs,
typename Lhs::Scalar &res)
{
const int i = Index - 1;
EiMatrixProductUnroller<Index-1, Size, Lhs, Rhs>::run(row, col, lhs, rhs, res);
if(i == Size - 1)
res = lhs.read(row, i) * rhs.read(i, col);
else
res += lhs.read(row, i) * rhs.read(i, col);
res += lhs.read(row, Index) * rhs.read(Index, col);
}
};
@ -126,16 +122,12 @@ struct EiMatrixProductUnroller<0, Size, Lhs, Rhs>
static void run(int row, int col, const Lhs& lhs, const Rhs& rhs,
typename Lhs::Scalar &res)
{
EI_UNUSED(row);
EI_UNUSED(col);
EI_UNUSED(lhs);
EI_UNUSED(rhs);
EI_UNUSED(res);
res = lhs.read(row, 0) * rhs.read(0, col);
}
};
template<int Size, typename Lhs, typename Rhs>
struct EiMatrixProductUnroller<EiDynamic, Size, Lhs, Rhs>
template<int Index, typename Lhs, typename Rhs>
struct EiMatrixProductUnroller<Index, EiDynamic, Lhs, Rhs>
{
static void run(int row, int col, const Lhs& lhs, const Rhs& rhs,
typename Lhs::Scalar &res)
@ -181,7 +173,7 @@ template<typename Lhs, typename Rhs> class EiMatrixProduct
{
Scalar res;
if(Lhs::ColsAtCompileTime != EiDynamic && Lhs::ColsAtCompileTime <= 16)
EiMatrixProductUnroller<Lhs::ColsAtCompileTime, Lhs::ColsAtCompileTime, LhsRef, RhsRef>
EiMatrixProductUnroller<Lhs::ColsAtCompileTime-1, Lhs::ColsAtCompileTime, LhsRef, RhsRef>
::run(row, col, m_lhs, m_rhs, res);
else
{

View File

@ -30,12 +30,8 @@ template<int Index, int Rows, typename Derived> struct EiTraceUnroller
{
static void run(const Derived &mat, typename Derived::Scalar &trace)
{
const int i = Index - 1;
EiTraceUnroller<Index-1, Rows, Derived>::run(mat, trace);
if(i == Rows - 1)
trace = mat(i, i);
else
trace += mat(i, i);
trace += mat(Index, Index);
}
};
@ -43,12 +39,11 @@ template<int Rows, typename Derived> struct EiTraceUnroller<0, Rows, Derived>
{
static void run(const Derived &mat, typename Derived::Scalar &trace)
{
EI_UNUSED(mat);
EI_UNUSED(trace);
trace = mat(0, 0);
}
};
template<int Rows, typename Derived> struct EiTraceUnroller<EiDynamic, Rows, Derived>
template<int Index, typename Derived> struct EiTraceUnroller<Index, EiDynamic, Derived>
{
static void run(const Derived &mat, typename Derived::Scalar &trace)
{
@ -63,7 +58,7 @@ Scalar EiObject<Scalar, Derived>::trace() const
assert(rows() == cols());
Scalar res;
if(RowsAtCompileTime != EiDynamic && RowsAtCompileTime <= 16)
EiTraceUnroller<RowsAtCompileTime, RowsAtCompileTime, Derived>
EiTraceUnroller<RowsAtCompileTime-1, RowsAtCompileTime, Derived>
::run(*static_cast<const Derived*>(this), res);
else
{