Real that uses Fast2Sum for addition
authorSam Moore <matches@ucc.asn.au>
Mon, 21 Apr 2014 16:55:49 +0000 (00:55 +0800)
committerSam Moore <matches@ucc.asn.au>
Mon, 21 Apr 2014 16:55:49 +0000 (00:55 +0800)
I have a feeling this isn't going to improve things at all.

src/ipdf.h
src/main.cpp
src/main.h
src/real.cpp
src/real.h
src/real_fast2sum.h [new file with mode: 0644]
src/tests/calculatepi.cpp
src/tests/realops.cpp [new file with mode: 0644]

index c9a6a23..79d25a8 100644 (file)
@@ -13,7 +13,7 @@ namespace IPDF
 
        inline Real Random(Real max=1, Real min=0)
        {
-               return min + (max-min) * ((Real)(rand() % (int)1e6) / 1e6);
+               return min + (max-min) * (Real(rand() % (int)1e6) / Real(1e6));
        }
 
        typedef unsigned ObjectID;
@@ -31,10 +31,11 @@ namespace IPDF
                Real x; Real y; Real w; Real h;
                Rect() = default; // Needed so we can fread/fwrite this struct
                Rect(Real _x, Real _y, Real _w, Real _h) : x(_x), y(_y), w(_w), h(_h) {}
-               std::string Str() 
+               std::string Str() const
                {
                        std::stringstream s;
-                       s << "{" << x << ", " << y << ", " << w << ", " << h << "}";
+                       // float conversion needed because it is fucking impossible to get ostreams working with template classes
+                       s << "{" << Float(x) << ", " << Float(y) << ", " << Float(w) << ", " << Float(h) << "}";
                        return s.str();
                }
        };
index 9b33453..e5e7947 100644 (file)
@@ -81,9 +81,9 @@ int main(int argc, char ** argv)
        }
        else 
        {
-               for(int i = 0; i < 1024; ++i)
+               for(int i = 0; i < 8; ++i)
                {
-                       for (int j = 0; j < 1024; ++j)
+                       for (int j = 0; j < 8; ++j)
                        {
                                doc.Add(((i^j)&1)?RECT_OUTLINE:RECT_FILLED, Rect(0.2+i-512.0,0.2+j-512.0,0.6,0.6));
                        }
index bfd9fac..7d586ce 100644 (file)
@@ -71,7 +71,7 @@ inline void MainLoop(Document & doc, const Rect & bounds = Rect(0,0,1,1), const
                scr.Clear();
                view.Render();
                scr.DebugFontPrintF("[CPU] Render took %lf ms (%lf FPS)\n", (SDL_GetPerformanceCounter() - init_time)* 1000.0/SDL_GetPerformanceFrequency(), SDL_GetPerformanceFrequency()/(SDL_GetPerformanceCounter() - init_time));
-               scr.DebugFontPrintF("View bounds: (%f, %f) - (%f, %f)\n", view.GetBounds().x, view.GetBounds().y, view.GetBounds().w, view.GetBounds().h);
+               scr.DebugFontPrintF("View bounds: %s\n", view.GetBounds().Str().c_str());
                if (view.UsingGPUTransform())
                {
                        scr.DebugFontPrint("Doing coordinate transform on the GPU.\n");
index 7c70a92..bda6102 100644 (file)
@@ -6,7 +6,8 @@ namespace IPDF
        const char * g_real_name[] = {
                "single",
                "double",
-               "long double"
+               "long double",
+               "single [fast2sum]"
        };
 
 }
index 0068472..4a81227 100644 (file)
@@ -6,11 +6,16 @@
 #define REAL_SINGLE 0
 #define REAL_DOUBLE 1
 #define REAL_LONG_DOUBLE 2
+#define REAL_SINGLE_FAST2SUM 3
 
 #ifndef REAL
        #error "REAL was not defined!"
 #endif
 
+#if REAL >= REAL_SINGLE_FAST2SUM
+       #include "real_fast2sum.h"
+#endif //REAL
+
 namespace IPDF
 {      
        extern const char * g_real_name[];
@@ -24,6 +29,10 @@ namespace IPDF
 #elif REAL == REAL_LONG_DOUBLE
        typedef long double Real;
        inline long double Float(Real r) {return r;}
+#elif REAL == REAL_SINGLE_FAST2SUM
+       typedef RealF2S<float> Real;
+       inline float Float(Real r) {return r.m_value;}
+               
 #else
        #error "Type of Real unspecified."
 #endif //REAL
diff --git a/src/real_fast2sum.h b/src/real_fast2sum.h
new file mode 100644 (file)
index 0000000..d621440
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _REAL_FAST2SUM_H
+#define _REAL_FAST2SUM_H
+
+#include <cmath>
+// otherwise the abs() function won't work
+
+namespace IPDF
+{
+
+       template <class T = float>
+       struct RealF2S
+       {
+               RealF2S(const T & value = 0.0L) : m_value(value) {} //{Debug("Construct from value %f", m_value);}
+               RealF2S(const RealF2S & cpy) : m_value(cpy.m_value) {} //{Debug("Copy construct from value %f", m_value);}
+
+               RealF2S & operator+=(const RealF2S & a) {this->operator=(RealF2S(*this) + a); return *this;}
+               RealF2S & operator-=(const RealF2S & a) {this->operator=(RealF2S(*this) - a); return *this;}
+               RealF2S & operator*=(const RealF2S & a) {this->operator=(RealF2S(*this) * a); return *this;}
+               RealF2S & operator/=(const RealF2S & a) {this->operator=(RealF2S(*this) / a); return *this;}
+
+               RealF2S & operator=(const RealF2S & equ) {this->m_value = equ.m_value; return *this;}
+               RealF2S & operator=(const T & equ) {this->m_value = equ.m_value; return *this;}
+
+               T m_value;
+       };
+
+       
+
+       template <class T> RealF2S<T> operator+(const RealF2S<T> & a, const RealF2S<T> & b)
+       {
+               // Use fast2sum
+               if (abs(T(a.m_value)) < abs(T(b.m_value)))
+                       return b+a;
+               T z = a.m_value + b.m_value;
+               T w = z - a.m_value;
+               T zz = b.m_value - w;
+               return RealF2S<T>(z + zz);
+       }
+       template <class T> RealF2S<T> operator-(const RealF2S<T> & a, const RealF2S<T> & b)
+       {
+               // Use fast2sum
+               return a + RealF2S<T>(-b.m_value);
+       }
+
+       template <class T> RealF2S<T> operator*(const RealF2S<T> & a, const RealF2S<T> & b)
+       {
+               return RealF2S<T>(a.m_value * b.m_value);
+       }
+       template <class T> RealF2S<T> operator/(const RealF2S<T> & a, const RealF2S<T> & b)
+       {
+               return RealF2S<T>(a.m_value / b.m_value);
+       }
+
+
+}
+
+#endif //_REAL_FAST2SUM_H
index 0b7692b..ea9ea8f 100644 (file)
@@ -68,7 +68,7 @@ int main(int argc, char ** argv)
                #if REAL > REAL_LONG_DOUBLE
                        Real error_real = Integrate<Real>(f<Real>,Real(0.0L), Real(1.0L), intervals) - Real(PI);
                        clock_t clock_real = clock() - start;   
-                       printf("\t%.30lf\t%li\n", error_real, clock_real);
+                       printf("\t%.30lf\t%li\n", Float(error_real), clock_real);
                #else
                        printf("\n");
                #endif
diff --git a/src/tests/realops.cpp b/src/tests/realops.cpp
new file mode 100644 (file)
index 0000000..2ccba67
--- /dev/null
@@ -0,0 +1,26 @@
+#include "main.h"
+#include "real.h"
+
+using namespace std;
+using namespace IPDF;
+
+
+int main(int argc, char ** argv)
+{
+       srand(time(NULL));
+       Real a = Random(100);
+       Real b = Random(100);
+       Debug("a = %f", Float(a));
+       Debug("b = %f", Float(b));
+       Debug("a + b = %f", Float(a + b));
+       Debug("a - b = %f", Float(a - b));
+       Debug("a * b = %f", Float(a * b));
+       Debug("a / b = %f", Float(a / b));
+       Debug("a += b => %f", Float(a += b));
+       Debug("a -= b => %f", Float(a -= b));
+       Debug("a *= b => %f", Float(a *= b));
+       Debug("a /= b => %f", Float(a /= b));
+       Debug("a = %f", Float(a));
+       Debug("b = %f", Float(b));
+
+}

UCC git Repository :: git.ucc.asn.au