chiark / gitweb /
hayai not flexible enough. Write new benchmarker without it.
authorRoss Younger <onyx-commits@impropriety.org.uk>
Thu, 4 Apr 2013 09:59:45 +0000 (22:59 +1300)
committerRoss Younger <onyx-commits@impropriety.org.uk>
Thu, 4 Apr 2013 09:59:45 +0000 (22:59 +1300)
Makefile.am
benchmark/Benchmarkable.cpp [new file with mode: 0644]
benchmark/Benchmarkable.h [new file with mode: 0644]
benchmark/benchmark2.cpp [new file with mode: 0644]

index b35a895..26a3657 100644 (file)
@@ -146,10 +146,10 @@ libhayai_a_SOURCES= hayai/hayai.hpp hayai/hayai-posixmain.cpp \
 ################################################################
 
 check_PROGRAMS+=b2benchmark
-b2benchmark_SOURCES=benchmark/benchmark.cpp
+b2benchmark_SOURCES=benchmark/benchmark2.cpp benchmark/Benchmarkable.cpp
 
-b2benchmark_LDADD= libhayai.a libfractal.a
-b2benchmark_DEPENDENCIES= libhayai.a libfractal.a
+b2benchmark_LDADD= libfractal.a
+b2benchmark_DEPENDENCIES= libfractal.a
 b2benchmark_CPPFLAGS=$(AM_CPPFLAGS)
 
 benchmark: b2benchmark
diff --git a/benchmark/Benchmarkable.cpp b/benchmark/Benchmarkable.cpp
new file mode 100644 (file)
index 0000000..213c049
--- /dev/null
@@ -0,0 +1,27 @@
+/*  Benchmarkable.cpp: Framework for benchmark suite
+    Copyright (C) 2013 Ross Younger
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Benchmarkable.h"
+#include <sys/time.h>
+
+uint64_t Benchmarkable::benchmark() {
+    struct timeval t_start, t_end;
+    gettimeofday(&t_start, 0);
+       run();
+    gettimeofday(&t_end, 0);
+    return 1000000 * (t_end.tv_sec - t_start.tv_sec) + t_end.tv_usec - t_start.tv_usec;
+}
diff --git a/benchmark/Benchmarkable.h b/benchmark/Benchmarkable.h
new file mode 100644 (file)
index 0000000..02155b2
--- /dev/null
@@ -0,0 +1,41 @@
+/*  Benchmarkable.cpp: Framework for benchmark suite
+    Copyright (C) 2013 Ross Younger
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BENCHMARKABLE_H_
+#define BENCHMARKABLE_H_
+
+#include <stdint.h>
+
+class Benchmarkable
+{
+public:
+       Benchmarkable() {}
+
+       // Actually runs the benchmark.
+       // Returns the runtime in microseconds.
+       // NOTE: When committing statistics you should pay attention to n_iterations().
+       uint64_t benchmark();
+       // How many iterations did we benchmark?
+       virtual uint64_t n_iterations() = 0;
+protected:
+       // Code to be benchmarked
+       virtual void run() = 0;
+
+       virtual ~Benchmarkable() {}
+};
+
+#endif /* BENCHMARKABLE_H_ */
diff --git a/benchmark/benchmark2.cpp b/benchmark/benchmark2.cpp
new file mode 100644 (file)
index 0000000..34e4ef3
--- /dev/null
@@ -0,0 +1,100 @@
+/*  benchmark2.cpp: brot2 basic benchmark suite, second try
+    Copyright (C) 2013 Ross Younger
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Fractal.h"
+#include "Exception.h"
+#include "Benchmarkable.h"
+#include <iomanip>
+
+using namespace Fractal;
+using namespace std;
+
+class FractalBM : public Benchmarkable
+{
+public:
+       FractalImpl *impl;
+       Point coords;
+       PointData data;
+       Maths::MathsType ty;
+       const uint64_t _N;
+
+       FractalBM(Maths::MathsType maths) : impl(0), ty(maths), _N(1<<26) {
+               FractalCommon::load_base();
+               impl = FractalCommon::registry.get("Mandelbrot");
+               if (impl==0) THROW(BrotFatalException, "Cannot find my fractal!");
+
+               /* A point (found by experiment) that's in the set but not
+                * in the special-case cut-off regions */
+               coords = { -0.1586536, 1.034804 };
+               // coords = { -1.563, -0.0625 }; // Mandeldrop
+       }
+
+       virtual uint64_t n_iterations() { return _N; }
+
+protected:
+       virtual void run() {
+               impl->prepare_pixel(coords, data);
+               impl->plot_pixel(_N, data, ty);
+               /* Note that plot_pixel converts the point data from the base type
+                * to the templated type - but only once per call. */
+       }
+};
+
+const string YELLOW("\033[0;33m");
+const string DEFAULT("\033[m");
+
+
+struct stats {
+       string title;
+       uint64_t time;
+       uint64_t n_iters;
+
+       stats(const string& _title, uint64_t _time, uint64_t _n_iters) :
+               title(_title), time(_time), n_iters(_n_iters) {}
+
+       void output() const {
+               uint64_t sec = time / 1000000, usec = time % 1000000;
+               long double mean_us = time * 1000000 / n_iters;
+
+               cout << resetiosflags(ios::showbase)
+                    << YELLOW
+                        << "Benchmark:               " << title << endl
+                    << DEFAULT
+                    << setw(3)
+                    << "Total time:              " << sec << '.' << setfill('0') << setw(6) << usec << 's' << endl
+                    << resetiosflags(ios::showbase)
+                    << "Number of iterations:    " << n_iters << endl
+                    << "Mean time per iteration: " << mean_us << "us" << endl
+                    << endl;
+       }
+};
+
+void do_bm(Maths::MathsType mt, const string& title) {
+       FractalBM bm(mt);
+
+       struct stats st(title, bm.benchmark(), bm.n_iterations());
+       st.output();
+}
+
+#define DO_BENCHMARK(type,name,minpix) \
+       do_bm(Maths::MathsType::name, #name);
+
+int main(int argc, char**argv) {
+       ALL_MATHS_TYPES(DO_BENCHMARK);
+       (void) argc;
+       (void) argv;
+}