sc/source/core/inc/arraysumfunctor.hxx |   25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

New commits:
commit 36f35bd823ef9af454f1d4609ad302acbef0709b
Author:     dante <dante19031...@gmail.com>
AuthorDate: Tue May 4 21:06:19 2021 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Wed May 5 07:15:51 2021 +0200

    Use kahan Sum for ArraySumFunctor
    
    Change-Id: I2f00d3c4c04f1c65083137d36772728a1eae0bed
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115112
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sc/source/core/inc/arraysumfunctor.hxx 
b/sc/source/core/inc/arraysumfunctor.hxx
index 62847493b88a..ae8d38db1338 100644
--- a/sc/source/core/inc/arraysumfunctor.hxx
+++ b/sc/source/core/inc/arraysumfunctor.hxx
@@ -17,6 +17,7 @@
 #include <sal/types.h>
 #include <tools/simd.hxx>
 #include <tools/cpuid.hxx>
+#include <kahan.hxx>
 
 namespace sc
 {
@@ -33,11 +34,11 @@ public:
     {
     }
 
-    double operator()()
+    KahanSum operator()()
     {
         const static bool hasSSE2 = cpuid::hasSSE2();
 
-        double fSum = 0.0;
+        KahanSum fSum = 0.0;
         size_t i = 0;
         const double* pCurrent = mpArray;
 
@@ -54,7 +55,7 @@ public:
             }
         }
         else
-            fSum += executeUnrolled(i, pCurrent);
+            fSum = executeUnrolled(i, pCurrent);
 
         // sum rest of the array
 
@@ -63,9 +64,10 @@ public:
 
         // If the sum is a NaN, some of the terms were empty cells, probably.
         // Re-calculate, carefully
-        if (!std::isfinite(fSum))
+        double fVal = fSum.get();
+        if (!std::isfinite(fVal))
         {
-            sal_uInt32 nErr = 
reinterpret_cast<sal_math_Double*>(&fSum)->nan_parts.fraction_lo;
+            sal_uInt32 nErr = 
reinterpret_cast<sal_math_Double*>(&fVal)->nan_parts.fraction_lo;
             if (nErr & 0xffff0000)
             {
                 fSum = 0;
@@ -88,17 +90,17 @@ public:
 
 private:
     double executeSSE2(size_t& i, const double* pCurrent) const;
-    double executeUnrolled(size_t& i, const double* pCurrent) const
+    KahanSum executeUnrolled(size_t& i, const double* pCurrent) const
     {
         size_t nRealSize = mnSize - i;
         size_t nUnrolledSize = nRealSize - (nRealSize % 4);
 
         if (nUnrolledSize > 0)
         {
-            double sum0 = 0.0;
-            double sum1 = 0.0;
-            double sum2 = 0.0;
-            double sum3 = 0.0;
+            KahanSum sum0 = 0.0;
+            KahanSum sum1 = 0.0;
+            KahanSum sum2 = 0.0;
+            KahanSum sum3 = 0.0;
 
             for (; i < nUnrolledSize; i += 4)
             {
@@ -107,7 +109,8 @@ private:
                 sum2 += *pCurrent++;
                 sum3 += *pCurrent++;
             }
-            return sum0 + sum1 + sum2 + sum3;
+            // We are using pairwise summation alongside Kahan
+            return (sum0 + sum1) + (sum2 + sum3);
         }
         return 0.0;
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to