Hi Kohei, I'd love some input (if you have a minute) on the attached. The punch-line is, that if we want to do really fast arithmetic, we start to need to do some odd things; while I suspect that this piece of unrolling can be done with the iterator - the next step I'm poking at (SSE3 assembler ;-) is not going to like that.
The win from this on a sum heavy sheet calculation is from 14.4s seconds to recalculate to 9s (actually testing using the 'puncture_mdds_encap' approach ;-) - a 35%+ speedup. I guess, what I'd most like is a: 'const double *getDoubles(size_t nAtOffset); Or somesuch =) or, failing that - a chunked double iterator that would give a pointer and size (reflecting the underlying chunks but giving some freedom there). Thoughts much appreciated =) ATB, Michael. -- michael.me...@collabora.com <><, Pseudo Engineer, itinerant idiot
commit 5c3fd002727197d5c4867503b799662193608ce0 Author: Michael Meeks <michael.me...@collabora.com> Date: Sat Oct 24 22:56:39 2015 +0100 Adapt FuncSum to vectorize better - potentially ... Change-Id: Ife1523538d4086b0072ca14c768358f4dd3396ab diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index e02abbc..4caf175 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -203,6 +203,11 @@ double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda ) namespace { +// this is unpleasant - but ... we want raw access. +struct puncture_mdds_encap : public sc::numeric_block { + const double *getPtr(size_t nOffset) const { return &m_array[nOffset]; } +}; + class NumericCellAccumulator { double mfSum; @@ -211,32 +216,63 @@ class NumericCellAccumulator public: NumericCellAccumulator() : mfSum(0.0), mnError(0) {} - void operator() (size_t, double fVal) + void operator() (const sc::CellStoreType::value_type& rNode, size_t nOffset, size_t nDataSize) { - mfSum += fVal; - } + switch (rNode.type) + { + case sc::element_type_numeric: + { + sc::numeric_block::const_iterator it = sc::numeric_block::begin(*rNode.data); + std::advance(it, nOffset); + const double *p = &(*it); // FIXME - this is not ideal at all ... +#if 0 + const puncture_mdds_encap *pBlock = static_cast<const puncture_mdds_encap *>(rNode.data); + const double *p = pBlock->getPtr(nOffset); +#endif + size_t i, nUnrolled = (nDataSize & 0x3) >> 2; + + // Try to encourage the compiler/CPU to do something sensible (?) + for (i = 0; i < nUnrolled; i+=4) + { + mfSum += p[i]; + mfSum += p[i+1]; + mfSum += p[i+2]; + mfSum += p[i+3]; + } + for (; i < nDataSize; ++i) + mfSum += p[i]; + break; + } - void operator() (size_t, const ScFormulaCell* pCell) - { - if (mnError) - // Skip all the rest if we have an error. - return; + 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; - 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; + if (nErr) + { + // Cell has error - skip all the rest + mnError = nErr; + return; + } - if (nErr) - { - // Cell has error. - mnError = nErr; - return; + mfSum += fVal; + } + } + break; + default: + ; } - - mfSum += fVal; } sal_uInt16 getError() const { return mnError; } @@ -335,7 +371,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;
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice