Nicolas Winkler 5 jaren geleden
bovenliggende
commit
2c9038f7ac
4 gewijzigde bestanden met toevoegingen van 82 en 3 verwijderingen
  1. 69 0
      libmandel/include/Fixed.h
  2. 8 2
      libmandel/include/Types.h
  3. 3 0
      libmandel/src/CpuGenerators.cpp
  4. 2 1
      libmandel/src/Mandel.cpp

+ 69 - 0
libmandel/include/Fixed.h

@@ -7,6 +7,75 @@
 #include <array>
 #include <vector>
 
+#include <boost/multiprecision/cpp_int.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+
+
+struct Fixed512
+{
+    using Once = boost::multiprecision::int512_t;
+    using Twice = boost::multiprecision::int1024_t;
+
+    Once body;
+
+    inline explicit Fixed512(const Once& body) :
+        body{ body }
+    {}
+
+    using Float256 = boost::multiprecision::number<
+        boost::multiprecision::backends::cpp_bin_float<
+            240, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
+            boost::multiprecision::et_off>;
+
+    inline Fixed512(const Float256& val)
+    {
+        body = Once{ val * boost::multiprecision::pow(Float256{2}, 512 - 32) };
+    }
+
+    inline Fixed512(double val)
+    {
+        body = Once{ boost::multiprecision::pow(Float256{2}, 512 - 32) * val };
+    }
+
+    inline operator Float256(void) const {
+        return boost::multiprecision::pow(Float256{ 0.5 }, 512 - 32) * Float256{ body };
+    }
+
+    inline Fixed512& operator += (const Fixed512& other) {
+        body += other.body;
+        return *this;
+    }
+
+    inline Fixed512 operator + (const Fixed512& other) const {
+        return Fixed512{ body + other.body };
+    }
+
+    inline Fixed512& operator -= (const Fixed512& other) {
+        body -= other.body;
+        return *this;
+    }
+
+    inline Fixed512 operator - (const Fixed512& other) const {
+        return Fixed512{ body - other.body };
+    }
+
+    inline Fixed512 operator * (const Fixed512& other) const {
+        auto prod = Twice{ this->body } * other.body;
+        return Fixed512{ Once{ prod >> (512 - 64) } };
+    }
+
+    inline Fixed512& operator *= (const Fixed512& other) {
+        auto prod = Twice{ this->body } * other.body;
+        body = Once{ prod >> (512 - 64) };
+        return *this;
+    }
+
+    inline bool operator > (const Fixed512& other) {
+        return this->body > other.body;
+    }
+};
+
+
 struct Fixed128
 {
     uint64_t upper;

+ 8 - 2
libmandel/include/Types.h

@@ -110,7 +110,7 @@ namespace mnd
         return float(x.x[0] + x.x[1]);
     }
 
-        template<>
+    template<>
     inline QuadDouble convert<QuadDouble, Real>(const Real& x)
     {
         std::string s = x.str();
@@ -120,7 +120,13 @@ namespace mnd
     template<>
     inline float convert<float, QuadDouble>(const QuadDouble& x)
     {
-        return float(x.x[0] + x.x[1]);
+        return float(x.x[0] + x.x[1] + x.x[2] + x.x[3]);
+    }
+
+    template<>
+    inline float convert<float, Fixed512>(const Fixed512& x)
+    {
+        return float(Real(x));
     }
 #endif
 

+ 3 - 0
libmandel/src/CpuGenerators.cpp

@@ -34,6 +34,9 @@ namespace mnd
 
     template class CpuGenerator<mnd::Float256, mnd::NONE, false>;
     template class CpuGenerator<mnd::Float256, mnd::NONE, true>;
+
+    template class CpuGenerator<Fixed512, mnd::NONE, false>;
+    template class CpuGenerator<Fixed512, mnd::NONE, true>;
 #endif
 
 #ifdef WITH_QD

+ 2 - 1
libmandel/src/Mandel.cpp

@@ -38,7 +38,8 @@ MandelContext::MandelContext(void)
 
 #if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) 
     if (cpuInfo.hasAvx()) {
-        auto fl = std::make_unique<CpuGenerator<float, mnd::X86_AVX, true>>();
+        //auto fl = std::make_unique<CpuGenerator<float, mnd::X86_AVX, true>>();
+        auto fl = std::make_unique<CpuGenerator<Fixed512, mnd::NONE, true>>();
         auto db = std::make_unique<CpuGenerator<double, mnd::X86_AVX, true>>();
         cpuGenerators.insert({ GeneratorType::FLOAT_AVX, std::move(fl) });
         cpuGenerators.insert({ GeneratorType::DOUBLE_AVX512, std::move(db) });