diff options
Diffstat (limited to 'Client/ThirdParty/fpm/benchmarks')
-rw-r--r-- | Client/ThirdParty/fpm/benchmarks/arithmetic.cpp | 58 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/benchmarks/benchmark.gnuplot | 20 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/benchmarks/benchmark.py | 67 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/benchmarks/power.cpp | 94 | ||||
-rw-r--r-- | Client/ThirdParty/fpm/benchmarks/trigonometry.cpp | 78 |
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>>); + |