aboutsummaryrefslogtreecommitdiff
path: root/Client/ThirdParty/fpm/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'Client/ThirdParty/fpm/benchmarks')
-rw-r--r--Client/ThirdParty/fpm/benchmarks/arithmetic.cpp58
-rw-r--r--Client/ThirdParty/fpm/benchmarks/benchmark.gnuplot20
-rw-r--r--Client/ThirdParty/fpm/benchmarks/benchmark.py67
-rw-r--r--Client/ThirdParty/fpm/benchmarks/power.cpp94
-rw-r--r--Client/ThirdParty/fpm/benchmarks/trigonometry.cpp78
5 files changed, 317 insertions, 0 deletions
diff --git a/Client/ThirdParty/fpm/benchmarks/arithmetic.cpp b/Client/ThirdParty/fpm/benchmarks/arithmetic.cpp
new file mode 100644
index 0000000..b2053cf
--- /dev/null
+++ b/Client/ThirdParty/fpm/benchmarks/arithmetic.cpp
@@ -0,0 +1,58 @@
+#include <benchmark/benchmark.h>
+#include <fpm/fixed.hpp>
+#include <cnl/fixed_point.h>
+
+#include <fixmath.h>
+
+#define BENCHMARK_TEMPLATE1_CAPTURE(func, test_case_name, a, ...) \
+ BENCHMARK_PRIVATE_DECLARE(func) = \
+ (::benchmark::internal::RegisterBenchmarkInternal( \
+ new ::benchmark::internal::FunctionBenchmark( \
+ #func "<" #a ">/" #test_case_name, \
+ [](::benchmark::State& st) { func<a>(st, __VA_ARGS__); })))
+
+// Constants for our arithmetic operands.
+// Stored as volatile to force the compiler to read them and
+// not optimize the entire expression into a constant.
+static volatile int16_t s_x = 1543;
+static volatile int16_t s_y = 2552;
+
+template <typename TValue>
+static void arithmetic(benchmark::State& state, TValue (*func)(TValue, TValue))
+{
+ for (auto _ : state)
+ {
+ TValue x{ static_cast<TValue>(static_cast<int16_t>(s_x)) }, y{ static_cast<TValue>(static_cast<int16_t>(s_y)) };
+ benchmark::DoNotOptimize(func(x, y));
+ }
+}
+
+#define FUNC(TYPE, OP) \
+ [](TYPE x, TYPE y) -> TYPE { return x OP y; }
+
+using CnlFixed16 = cnl::fixed_point<std::int32_t, -16>;
+
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, add, float, FUNC(float, +));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, sub, float, FUNC(float, -));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, mul, float, FUNC(float, *));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, div, float, FUNC(float, /));
+
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, add, double, FUNC(double, +));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, sub, double, FUNC(double, -));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, mul, double, FUNC(double, *));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, div, double, FUNC(double, /));
+
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, add, fpm::fixed_16_16, FUNC(fpm::fixed_16_16, +));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, sub, fpm::fixed_16_16, FUNC(fpm::fixed_16_16, -));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, mul, fpm::fixed_16_16, FUNC(fpm::fixed_16_16, *));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, div, fpm::fixed_16_16, FUNC(fpm::fixed_16_16, /));
+
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, add, Fix16, FUNC(Fix16, +));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, sub, Fix16, FUNC(Fix16, -));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, mul, Fix16, FUNC(Fix16, *));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, div, Fix16, FUNC(Fix16, /));
+
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, add, CnlFixed16, FUNC(CnlFixed16, +));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, sub, CnlFixed16, FUNC(CnlFixed16, -));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, mul, CnlFixed16, FUNC(CnlFixed16, *));
+BENCHMARK_TEMPLATE1_CAPTURE(arithmetic, div, CnlFixed16, FUNC(CnlFixed16, /));
diff --git a/Client/ThirdParty/fpm/benchmarks/benchmark.gnuplot b/Client/ThirdParty/fpm/benchmarks/benchmark.gnuplot
new file mode 100644
index 0000000..e97a3f3
--- /dev/null
+++ b/Client/ThirdParty/fpm/benchmarks/benchmark.gnuplot
@@ -0,0 +1,20 @@
+#!/usr/bin/gnuplot
+set terminal png size 860,350 font "Arial,8"
+set datafile separator ","
+set datafile missing "-"
+
+set style data histogram
+set style fill solid border linecolor black
+set style histogram clustered gap 2
+set boxwidth 1
+
+set key left top noenhanced
+
+set xtics scale 0
+set grid ytics
+set ylabel "avg. time (ns)"
+
+DATA_FILE="performance.csv"
+set output "performance.png"
+
+plot for [COL=2:6] DATA_FILE using COL:xtic(1) title columnheader \ No newline at end of file
diff --git a/Client/ThirdParty/fpm/benchmarks/benchmark.py b/Client/ThirdParty/fpm/benchmarks/benchmark.py
new file mode 100644
index 0000000..5e61b5d
--- /dev/null
+++ b/Client/ThirdParty/fpm/benchmarks/benchmark.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+"""
+Translates google benchmark JSON output to a format expected by gnuplot.
+"""
+import argparse
+import json
+import os
+import re
+import sys
+
+def sanitize_type(type):
+ if type == "Fix16":
+ return "fix16"
+ if type == "CnlFixed16":
+ return "cnl::fixed_16_16"
+ if type.startswith("fpm::fixed"):
+ return type
+ return type
+
+def parse_name(name):
+ # Expected format:
+ # test-class "<" float-type ">" "/" operation
+ result = re.match(r'^(.*)<(.*)>/([a-z0-9_]*)$', name)
+ if result:
+ return sanitize_type(result.group(2)), result.group(3)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('INFILE', help="the JSON file to process")
+ parser.add_argument('OUTFILE', help="the file to write GnuPlot data to")
+ args = parser.parse_args()
+
+ operation_data = {}
+ operations = []
+ types = []
+ with open(args.INFILE) as infile:
+ data = json.load(infile)
+ for entry in data['benchmarks']:
+ if entry['time_unit'] != 'ns':
+ raise ValueError("time_unit not in nanoseconds")
+
+ result = parse_name(entry['name'])
+ if result:
+ float_type, operation_name = result
+ if not operation_name in operations:
+ operations.append(operation_name)
+ if not float_type in types:
+ types.append(float_type)
+
+ d = operation_data.get(operation_name, {})
+ d[float_type] = entry['cpu_time']
+ operation_data[operation_name] = d
+
+ with open(args.OUTFILE, 'w') as outfile:
+ outfile.write("operation,{}\n".format(",".join(types)))
+ for operation_name in operations:
+ d = operation_data[operation_name]
+ data = []
+ for type in types:
+ data.append(str(d.get(type, "-")))
+ outfile.write("{},{}\n".format(operation_name, ",".join(data)))
+
+ return 0
+
+if __name__== "__main__":
+ sys.exit(main()) \ No newline at end of file
diff --git a/Client/ThirdParty/fpm/benchmarks/power.cpp b/Client/ThirdParty/fpm/benchmarks/power.cpp
new file mode 100644
index 0000000..7a9c407
--- /dev/null
+++ b/Client/ThirdParty/fpm/benchmarks/power.cpp
@@ -0,0 +1,94 @@
+#include <benchmark/benchmark.h>
+#include <fpm/fixed.hpp>
+#include <fpm/math.hpp>
+#include <cnl/fixed_point.h>
+#include <fixmath.h>
+
+#define BENCHMARK_TEMPLATE1_CAPTURE(func, test_case_name, a, ...) \
+ BENCHMARK_PRIVATE_DECLARE(func) = \
+ (::benchmark::internal::RegisterBenchmarkInternal( \
+ new ::benchmark::internal::FunctionBenchmark( \
+ #func "<" #a ">/" #test_case_name, \
+ [](::benchmark::State& st) { func<a>(st, __VA_ARGS__); })))
+
+template <fix16_t (*func)(fix16_t)>
+static Fix16 fix16_func(Fix16 f)
+{
+ return (*func)(f);
+}
+
+// Constants for our power function arguments.
+// Stored as volatile to force the compiler to read them and
+// not optimize the entire expression into a constant.
+static volatile int16_t s_x = 2734;
+static volatile int16_t s_y = 174;
+
+template <typename TValue>
+static void power1(benchmark::State& state, TValue (*func)(TValue))
+{
+ for (auto _ : state)
+ {
+ TValue x{ static_cast<TValue>(s_x / 256.0) };
+ benchmark::DoNotOptimize(func(x));
+ }
+}
+
+template <typename TValue>
+static void power1(benchmark::State& state, TValue (*func)(const TValue&))
+{
+ for (auto _ : state)
+ {
+ TValue x{ static_cast<TValue>(s_x / 256.0) };
+ benchmark::DoNotOptimize(func(x));
+ }
+}
+
+template <typename TValue>
+static void power2(benchmark::State& state, TValue (*func)(TValue, TValue))
+{
+ for (auto _ : state)
+ {
+ TValue x{ static_cast<TValue>(s_x / 256.0) };
+ TValue y{ static_cast<TValue>(s_y / 256.0) };
+ benchmark::DoNotOptimize(func(x, y));
+ }
+}
+
+using CnlFixed16 = cnl::fixed_point<std::int32_t, -16>;
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, sqrt, float, &std::sqrt);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, sqrt, double, &std::sqrt);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, sqrt, fpm::fixed_16_16, &fpm::sqrt);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, sqrt, Fix16, fix16_func<&fix16_sqrt>);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, sqrt, CnlFixed16, &cnl::sqrt);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, cbrt, float, &std::cbrt);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, cbrt, double, &std::cbrt);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, cbrt, fpm::fixed_16_16, &fpm::cbrt);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log, float, &std::log);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log, double, &std::log);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log, fpm::fixed_16_16, &fpm::log);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log2, float, &std::log2);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log2, double, &std::log2);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log2, fpm::fixed_16_16, &fpm::log2);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log2, Fix16, fix16_func<&fix16_log2>);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log10, float, &std::log10);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log10, double, &std::log10);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, log10, fpm::fixed_16_16, &fpm::log10);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp, float, &std::exp);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp, double, &std::exp);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp, fpm::fixed_16_16, &fpm::exp);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp, Fix16, fix16_func<&fix16_exp>);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp, CnlFixed16, &cnl::exp);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp2, float, &std::exp2);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp2, double, &std::exp2);
+BENCHMARK_TEMPLATE1_CAPTURE(power1, exp2, fpm::fixed_16_16, &fpm::exp2);
+
+BENCHMARK_TEMPLATE1_CAPTURE(power2, pow, float, &std::pow);
+BENCHMARK_TEMPLATE1_CAPTURE(power2, pow, double, &std::pow);
+BENCHMARK_TEMPLATE1_CAPTURE(power2, pow, fpm::fixed_16_16, &fpm::pow);
diff --git a/Client/ThirdParty/fpm/benchmarks/trigonometry.cpp b/Client/ThirdParty/fpm/benchmarks/trigonometry.cpp
new file mode 100644
index 0000000..e55dadf
--- /dev/null
+++ b/Client/ThirdParty/fpm/benchmarks/trigonometry.cpp
@@ -0,0 +1,78 @@
+#include <benchmark/benchmark.h>
+#include <fpm/fixed.hpp>
+#include <fpm/math.hpp>
+#include <fixmath.h>
+
+#define BENCHMARK_TEMPLATE1_CAPTURE(func, test_case_name, a, ...) \
+ BENCHMARK_PRIVATE_DECLARE(func) = \
+ (::benchmark::internal::RegisterBenchmarkInternal( \
+ new ::benchmark::internal::FunctionBenchmark( \
+ #func "<" #a ">/" #test_case_name, \
+ [](::benchmark::State& st) { func<a>(st, __VA_ARGS__); })))
+
+template <Fix16 (Fix16::*func)() const>
+static Fix16 fix16_func1(Fix16 f)
+{
+ return (f.*func)();
+}
+
+template <Fix16 (Fix16::*func)(const Fix16&) const>
+static Fix16 fix16_func2(Fix16 f, Fix16 y)
+{
+ return (f.*func)(y);
+}
+
+// Constant for our trigonometry function argument.
+// Stored as volatile to force the compiler to read them and
+// not optimize the entire expression into a constant.
+static volatile int16_t s_x = 174;
+
+template <typename TValue>
+static void trigonometry(benchmark::State& state, TValue (*func)(TValue))
+{
+ for (auto _ : state)
+ {
+ TValue x{ static_cast<TValue>(s_x / 256.0) };
+ benchmark::DoNotOptimize(func(x));
+ }
+}
+
+template <typename TValue, TValue (*func)(TValue, TValue)>
+static TValue func2_proxy(TValue value)
+{
+ // Add a 'random' offset for the second argument
+ return func(value, value + 2);
+}
+
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, sin, float, &std::sin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, cos, float, &std::cos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, tan, float, &std::tan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, asin, float, &std::asin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, acos, float, &std::acos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan, float, &std::atan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan2, float, &func2_proxy<float, &std::atan2>);
+
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, sin, double, &std::sin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, cos, double, &std::cos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, tan, double, &std::tan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, asin, double, &std::asin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, acos, double, &std::acos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan, double, &std::atan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan2, double, &func2_proxy<double, &std::atan2>);
+
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, sin, fpm::fixed_16_16, &fpm::sin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, cos, fpm::fixed_16_16, &fpm::cos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, tan, fpm::fixed_16_16, &fpm::tan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, asin, fpm::fixed_16_16, &fpm::asin);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, acos, fpm::fixed_16_16, &fpm::acos);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan, fpm::fixed_16_16, &fpm::atan);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan2, fpm::fixed_16_16, &func2_proxy<fpm::fixed_16_16, &fpm::atan2>);
+
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, sin, Fix16, fix16_func1<&Fix16::sin>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, cos, Fix16, fix16_func1<&Fix16::cos>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, tan, Fix16, fix16_func1<&Fix16::tan>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, asin, Fix16, fix16_func1<&Fix16::asin>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, acos, Fix16, fix16_func1<&Fix16::acos>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan, Fix16, fix16_func1<&Fix16::atan>);
+BENCHMARK_TEMPLATE1_CAPTURE(trigonometry, atan2, Fix16, &func2_proxy<Fix16, &fix16_func2<&Fix16::atan2>>);
+