From 5e19040b00e135ead52e535165e079ee72059727 Mon Sep 17 00:00:00 2001 From: Sam Moore Date: Tue, 22 Apr 2014 00:55:49 +0800 Subject: [PATCH] Real that uses Fast2Sum for addition I have a feeling this isn't going to improve things at all. --- src/ipdf.h | 7 ++--- src/main.cpp | 4 +-- src/main.h | 2 +- src/real.cpp | 3 ++- src/real.h | 9 +++++++ src/real_fast2sum.h | 57 +++++++++++++++++++++++++++++++++++++++ src/tests/calculatepi.cpp | 2 +- src/tests/realops.cpp | 26 ++++++++++++++++++ 8 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 src/real_fast2sum.h create mode 100644 src/tests/realops.cpp diff --git a/src/ipdf.h b/src/ipdf.h index c9a6a23..79d25a8 100644 --- a/src/ipdf.h +++ b/src/ipdf.h @@ -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(); } }; diff --git a/src/main.cpp b/src/main.cpp index 9b33453..e5e7947 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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)); } diff --git a/src/main.h b/src/main.h index bfd9fac..7d586ce 100644 --- a/src/main.h +++ b/src/main.h @@ -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"); diff --git a/src/real.cpp b/src/real.cpp index 7c70a92..bda6102 100644 --- a/src/real.cpp +++ b/src/real.cpp @@ -6,7 +6,8 @@ namespace IPDF const char * g_real_name[] = { "single", "double", - "long double" + "long double", + "single [fast2sum]" }; } diff --git a/src/real.h b/src/real.h index 0068472..4a81227 100644 --- a/src/real.h +++ b/src/real.h @@ -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 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 index 0000000..d621440 --- /dev/null +++ b/src/real_fast2sum.h @@ -0,0 +1,57 @@ +#ifndef _REAL_FAST2SUM_H +#define _REAL_FAST2SUM_H + +#include +// otherwise the abs() function won't work + +namespace IPDF +{ + + template + 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 RealF2S operator+(const RealF2S & a, const RealF2S & 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(z + zz); + } + template RealF2S operator-(const RealF2S & a, const RealF2S & b) + { + // Use fast2sum + return a + RealF2S(-b.m_value); + } + + template RealF2S operator*(const RealF2S & a, const RealF2S & b) + { + return RealF2S(a.m_value * b.m_value); + } + template RealF2S operator/(const RealF2S & a, const RealF2S & b) + { + return RealF2S(a.m_value / b.m_value); + } + + +} + +#endif //_REAL_FAST2SUM_H diff --git a/src/tests/calculatepi.cpp b/src/tests/calculatepi.cpp index 0b7692b..ea9ea8f 100644 --- a/src/tests/calculatepi.cpp +++ b/src/tests/calculatepi.cpp @@ -68,7 +68,7 @@ int main(int argc, char ** argv) #if REAL > REAL_LONG_DOUBLE Real error_real = Integrate(f,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 index 0000000..2ccba67 --- /dev/null +++ b/src/tests/realops.cpp @@ -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)); + +} -- 2.20.1