Pārlūkot izejas kodu

more mandel files

Nicolas Winkler 6 gadi atpakaļ
vecāks
revīzija
1e78372fed

+ 26 - 0
libmandel/include/CpuGenerators.h

@@ -0,0 +1,26 @@
+#ifndef MANDEL_CPUGENERATORS_H
+#define MANDEL_CPUGENERATORS_H
+
+#include "Generators.h"
+
+namespace mnd
+{
+    class CpuGeneratorFloat;
+    class CpuGeneratorDouble;
+}
+
+
+class mnd::CpuGeneratorFloat : public Generator
+{
+public:
+    virtual void generate(const MandelInfo& info, float* data);
+};
+
+
+class mnd::CpuGeneratorDouble : public Generator
+{
+public:
+    virtual void generate(const MandelInfo& info, float* data);
+};
+
+#endif // MANDEL_CPUGENERATORS_H

+ 26 - 0
libmandel/include/Hardware.h

@@ -0,0 +1,26 @@
+#ifndef MANDEL_HARDWARE_H
+#define MANDEL_HARDWARE_H
+
+#include <string>
+
+namespace mnd
+{
+    class CpuInfo;
+}
+
+class mnd::CpuInfo
+{
+    std::string vendor;
+    std::string brand;
+
+    bool avx;
+public:
+    CpuInfo(void);
+
+    inline const std::string& getVendor(void) const { return vendor; };
+    inline const std::string& getBrand(void) const { return brand; };
+
+    inline bool hasAvx(void) const { return avx; };
+};
+
+#endif // MANDEL_HARDWARE_H

+ 71 - 0
libmandel/src/CpuGenerators.cpp

@@ -0,0 +1,71 @@
+#include "CpuGenerators.h"
+
+#include <omp.h>
+
+#include <memory>
+
+using mnd::CpuGeneratorFloat;
+using mnd::CpuGeneratorDouble;
+
+
+void CpuGeneratorFloat::generate(const mnd::MandelInfo& info, float* data)
+{
+    const MandelViewport& view = info.view;
+    omp_set_num_threads(2 * omp_get_num_procs());
+#pragma omp parallel for
+    for (long j = 0; j < info.bHeight; j++) {
+        float y = float(view.y) + float(j) * float(view.height / info.bHeight);
+        long i = 0;
+        for (i; i < info.bWidth; i++) {
+            float x = float(view.x + double(i) * view.width / info.bWidth);
+
+            float a = x;
+            float b = y;
+
+            int k = 0;
+            for (k = 0; k < info.maxIter; k++) {
+                float aa = a * a;
+                float bb = b * b;
+                float ab = a * b;
+                a = aa - bb + x;
+                b = ab + ab + y;
+                if (aa + bb > 16) {
+                    break;
+                }
+            }
+            data[i + j * info.bWidth] = k;
+        }
+    }
+}
+
+
+void CpuGeneratorDouble::generate(const mnd::MandelInfo& info, float* data)
+{
+    const MandelViewport& view = info.view;
+    omp_set_num_threads(2 * omp_get_num_procs());
+#pragma omp parallel for
+    for (long j = 0; j < info.bHeight; j++) {
+        double y = double(view.y) + double(j) * double(view.height / info.bHeight);
+        long i = 0;
+        for (i; i < info.bWidth; i++) {
+            double x = view.x + double(i) * view.width / info.bWidth;
+
+            double a = x;
+            double b = y;
+
+            int k = 0;
+            for (k = 0; k < info.maxIter; k++) {
+                double aa = a * a;
+                double bb = b * b;
+                double ab = a * b;
+                a = aa - bb + x;
+                b = ab + ab + y;
+                if (aa + bb > 16) {
+                    break;
+                }
+            }
+            data[i + j * info.bWidth] = k;
+        }
+    }
+}
+

+ 65 - 0
libmandel/src/Hardware.cpp

@@ -0,0 +1,65 @@
+#include "Hardware.h"
+
+#include <array>
+#include <vector>
+#include <bitset>
+
+#include <intrin.h>
+
+using mnd::CpuInfo;
+
+
+CpuInfo::CpuInfo(void)
+{
+    std::array<int, 4> dat;
+    std::vector<std::array<int, 4>> cpuData;
+    std::vector<std::array<int, 4>> extData;
+
+    __cpuid(dat.data(), 0);
+    int nData = dat[0];
+    __cpuid(dat.data(), 0x80000000);
+    int nExtData = dat[0];
+
+    for (int i = 0; i <= nData; i++) {
+        __cpuidex(dat.data(), i, 0);
+        cpuData.push_back(dat);
+    }
+
+    for (int i = 0x80000000; i <= nExtData; i++) {
+        __cpuidex(dat.data(), i, 0);
+        extData.push_back(dat);
+    }
+
+
+    char vendor[32];
+    memset(vendor, 0, sizeof vendor);
+    *reinterpret_cast<int*>(vendor) = cpuData[0][1];
+    *reinterpret_cast<int*>(vendor + 4) = cpuData[0][3];
+    *reinterpret_cast<int*>(vendor + 8) = cpuData[0][2];
+    this->vendor = vendor;
+
+    char brand[64];
+    memset(brand, 0, sizeof brand);
+
+    if (nExtData >= 0x80000004) {
+        memcpy(brand, extData[2].data(), sizeof(dat));
+        memcpy(brand + 16, extData[3].data(), sizeof(dat));
+        memcpy(brand + 32, extData[4].data(), sizeof(dat));
+        this->brand = brand;
+
+        // trim
+        this->brand.erase(0, this->brand.find_first_not_of(" \n\r\t"));
+        this->brand.erase(this->brand.find_last_not_of(" \n\r\t") + 1);
+    }
+
+    std::bitset<32> ecx1;
+    std::bitset<32> edx1;
+
+    if (nData >= 1) {
+        ecx1 = cpuData[1][2];
+        edx1 = cpuData[1][3];
+    }
+
+    avx = ecx1[28];
+}
+