[Libreoffice-commits] core.git: sc/source

Michael Meeks michael.meeks at collabora.com
Sat Oct 31 03:25:50 PDT 2015


 sc/source/core/tool/interpr6.cxx |  100 ++++++++++++++++++++++++++-------------
 1 file changed, 68 insertions(+), 32 deletions(-)

New commits:
commit 258e48d6d9c0d2ea9621b248239c0e1708a85cda
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Oct 30 20:58:05 2015 +0000

    Adapt FuncSum to vectorize better.
    
    Change-Id: If9b06cb7f1e17ab434bb61656dc8cfe7cf170309
    Reviewed-on: https://gerrit.libreoffice.org/19698
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 68750f8..0ef3ac1 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();


More information about the Libreoffice-commits mailing list