diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-10-30 20:58:05 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-10-31 10:25:27 +0000 |
commit | 258e48d6d9c0d2ea9621b248239c0e1708a85cda (patch) | |
tree | 5aee3aad5d2893bb2886ffde082084d04cb4b51f | |
parent | cfbc36e2eade42e471056d3c32fc962cd3149c17 (diff) |
Adapt FuncSum to vectorize better.
Change-Id: If9b06cb7f1e17ab434bb61656dc8cfe7cf170309
Reviewed-on: https://gerrit.libreoffice.org/19698
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r-- | sc/source/core/tool/interpr6.cxx | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index 68750f89fd32..0ef3ac101d56 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -201,8 +201,6 @@ double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda ) return GetLowRegIGamma( fAlpha, fX / fLambda); } -namespace { - class NumericCellAccumulator { double mfFirst; @@ -212,38 +210,78 @@ class NumericCellAccumulator public: 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 ) - mfFirst = fVal; - else - mfRest += fVal; - } + switch (rNode.type) + { + case sc::element_type_numeric: + { + const double *p = &sc::numeric_block::at(*rNode.data, nOffset); + size_t i = 0; - void operator() (size_t, const ScFormulaCell* pCell) - { - if (mnError) - // Skip all the rest if we have an error. - return; + // Store the first non-zero value in mfFirst (for some reason). + if (!mfFirst) + { + for (i = 0; i < nDataSize; ++i) + { + if (!mfFirst) + mfFirst = p[i]; + else + break; + } + } + p += i; + nDataSize -= i; + if (nDataSize == 0) + return; - double fVal = 0.0; - 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; + size_t nUnrolled = (nDataSize & 0x3) >> 2; - if (nErr) - { - // Cell has error. - mnError = nErr; - return; - } + // Try to encourage the compiler/CPU to do something sensible for the next. + for (i = 0; i < nUnrolled; i+=4) + { + mfRest += p[i]; + mfRest += p[i+1]; + mfRest += p[i+2]; + mfRest += p[i+3]; + } + for (; i < nDataSize; ++i) + mfRest += p[i]; + break; + } - if ( !mfFirst ) - mfFirst = fVal; - else - mfRest += fVal; + case sc::element_type_formula: + { + sc::formula_block::const_iterator it = sc::formula_block::begin(*rNode.data); + 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; } @@ -345,7 +383,7 @@ public: return; 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(); if (mnError) return; @@ -418,8 +456,6 @@ void IterateMatrix( } } -} - double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) { short nParamCount = GetByte(); |