Kaydet (Commit) 258e48d6 authored tarafından Michael Meeks's avatar Michael Meeks

Adapt FuncSum to vectorize better.

Change-Id: If9b06cb7f1e17ab434bb61656dc8cfe7cf170309
Reviewed-on: https://gerrit.libreoffice.org/19698Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst cfbc36e2
...@@ -201,8 +201,6 @@ double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda ) ...@@ -201,8 +201,6 @@ double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda )
return GetLowRegIGamma( fAlpha, fX / fLambda); return GetLowRegIGamma( fAlpha, fX / fLambda);
} }
namespace {
class NumericCellAccumulator class NumericCellAccumulator
{ {
double mfFirst; double mfFirst;
...@@ -212,38 +210,78 @@ class NumericCellAccumulator ...@@ -212,38 +210,78 @@ class NumericCellAccumulator
public: public:
NumericCellAccumulator() : mfFirst(0.0), mfRest(0.0), mnError(0) {} NumericCellAccumulator() : mfFirst(0.0), mfRest(0.0), mnError(0) {}
void operator() (size_t, double fVal) void operator() (const sc::CellStoreType::value_type& rNode, size_t nOffset, size_t nDataSize)
{ {
if ( !mfFirst ) switch (rNode.type)
mfFirst = fVal; {
else case sc::element_type_numeric:
mfRest += fVal; {
} const double *p = &sc::numeric_block::at(*rNode.data, nOffset);
size_t i = 0;
void operator() (size_t, const ScFormulaCell* pCell) // Store the first non-zero value in mfFirst (for some reason).
{ if (!mfFirst)
if (mnError) {
// Skip all the rest if we have an error. for (i = 0; i < nDataSize; ++i)
return; {
if (!mfFirst)
mfFirst = p[i];
else
break;
}
}
p += i;
nDataSize -= i;
if (nDataSize == 0)
return;
double fVal = 0.0; size_t nUnrolled = (nDataSize & 0x3) >> 2;
sal_uInt16 nErr = 0;
ScFormulaCell& rCell = const_cast<ScFormulaCell&>(*pCell);
if (!rCell.GetErrorOrValue(nErr, fVal))
// The cell has neither error nor value. Perhaps string result.
return;
if (nErr) // Try to encourage the compiler/CPU to do something sensible for the next.
{ for (i = 0; i < nUnrolled; i+=4)
// Cell has error. {
mnError = nErr; mfRest += p[i];
return; mfRest += p[i+1];
} mfRest += p[i+2];
mfRest += p[i+3];
}
for (; i < nDataSize; ++i)
mfRest += p[i];
break;
}
if ( !mfFirst ) case sc::element_type_formula:
mfFirst = fVal; {
else sc::formula_block::const_iterator it = sc::formula_block::begin(*rNode.data);
mfRest += fVal; std::advance(it, nOffset);
sc::formula_block::const_iterator itEnd = it;
std::advance(itEnd, nDataSize);
for (; it != itEnd; ++it)
{
double fVal = 0.0;
sal_uInt16 nErr = 0;
ScFormulaCell& rCell = const_cast<ScFormulaCell&>(*(*it));
if (!rCell.GetErrorOrValue(nErr, fVal))
// The cell has neither error nor value. Perhaps string result.
continue;
if (nErr)
{
// Cell has error - skip all the rest
mnError = nErr;
return;
}
if ( !mfFirst )
mfFirst = fVal;
else
mfRest += fVal;
}
}
break;
default:
;
}
} }
sal_uInt16 getError() const { return mnError; } sal_uInt16 getError() const { return mnError; }
...@@ -345,7 +383,7 @@ public: ...@@ -345,7 +383,7 @@ public:
return; return;
NumericCellAccumulator aFunc; NumericCellAccumulator aFunc;
maPos.miCellPos = sc::ParseFormulaNumeric(maPos.miCellPos, mpCol->GetCellStore(), nRow1, nRow2, aFunc); maPos.miCellPos = sc::ParseBlock(maPos.miCellPos, mpCol->GetCellStore(), aFunc, nRow1, nRow2);
mnError = aFunc.getError(); mnError = aFunc.getError();
if (mnError) if (mnError)
return; return;
...@@ -418,8 +456,6 @@ void IterateMatrix( ...@@ -418,8 +456,6 @@ void IterateMatrix(
} }
} }
}
double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
{ {
short nParamCount = GetByte(); short nParamCount = GetByte();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment