aboutsummaryrefslogtreecommitdiff
path: root/Client/ThirdParty/libfixmath/benchmarks/benchmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'Client/ThirdParty/libfixmath/benchmarks/benchmark.c')
-rw-r--r--Client/ThirdParty/libfixmath/benchmarks/benchmark.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/Client/ThirdParty/libfixmath/benchmarks/benchmark.c b/Client/ThirdParty/libfixmath/benchmarks/benchmark.c
new file mode 100644
index 0000000..3942abc
--- /dev/null
+++ b/Client/ThirdParty/libfixmath/benchmarks/benchmark.c
@@ -0,0 +1,201 @@
+#ifndef NO_FLOAT
+#include <math.h>
+#endif
+
+#include <fix16.h>
+#include "interface.h"
+#include <stdio.h>
+
+/* Autogenerated testcases */
+#include "testcases.c"
+
+// Initializer for cyclecount_t structure.
+// Max is initialized to 0 and min is 2^32-1 so that first call to cyclecount_update will set them.
+#define CYCLECOUNT_INIT {0xFFFFFFFF, 0, 0, 0}
+
+// Update cyclecount_t structure after a single measurement has been made.
+static void cyclecount_update(cyclecount_t *data, uint32_t cycles)
+{
+ if (cycles < data->min)
+ data->min = cycles;
+ if (cycles > data->max)
+ data->max = cycles;
+
+ data->sum += cycles;
+ data->count++;
+}
+
+#define MEASURE(variable, statement) { \
+ start_timing(); \
+ statement; \
+ cyclecount_update(&variable, end_timing()); \
+}
+
+static cyclecount_t exp_cycles = CYCLECOUNT_INIT;
+static cyclecount_t sqrt_cycles = CYCLECOUNT_INIT;
+static cyclecount_t add_cycles = CYCLECOUNT_INIT;
+static cyclecount_t sub_cycles = CYCLECOUNT_INIT;
+static cyclecount_t div_cycles = CYCLECOUNT_INIT;
+static cyclecount_t mul_cycles = CYCLECOUNT_INIT;
+
+static cyclecount_t float_sqrtf_cycles = CYCLECOUNT_INIT;
+static cyclecount_t float_expf_cycles = CYCLECOUNT_INIT;
+static cyclecount_t float_add_cycles = CYCLECOUNT_INIT;
+static cyclecount_t float_sub_cycles = CYCLECOUNT_INIT;
+static cyclecount_t float_div_cycles = CYCLECOUNT_INIT;
+static cyclecount_t float_mul_cycles = CYCLECOUNT_INIT;
+
+static fix16_t delta(fix16_t result, fix16_t expected)
+{
+#ifdef FIXMATH_NO_OVERFLOW
+ // Ignore overflow errors when the detection is turned off
+ if (expected == fix16_minimum)
+ return 0;
+#endif
+
+ if (result >= expected)
+ {
+ return result - expected;
+ }
+ else
+ {
+ return expected - result;
+ }
+}
+
+#ifdef FIXMATH_NO_ROUNDING
+const fix16_t max_delta = 1;
+#else
+const fix16_t max_delta = 0;
+#endif
+
+int main()
+{
+ int i;
+ interface_init();
+
+ start_timing();
+ print_value("Timestamp bias", end_timing());
+
+ for (i = 0; i < TESTCASES1_COUNT; i++)
+ {
+ fix16_t input = testcases1[i].a;
+ fix16_t result;
+ fix16_t expected = testcases1[i].sqrt;
+ MEASURE(sqrt_cycles, result = fix16_sqrt(input));
+
+ if (input > 0 && delta(result, expected) > max_delta)
+ {
+ print_value("Failed SQRT, i", i);
+ print_value("Failed SQRT, input", input);
+ print_value("Failed SQRT, output", result);
+ print_value("Failed SQRT, expected", expected);
+ }
+
+ expected = testcases1[i].exp;
+ MEASURE(exp_cycles, result = fix16_exp(input));
+
+ if (delta(result, expected) > 400)
+ {
+ print_value("Failed EXP, i", i);
+ print_value("Failed EXP, input", input);
+ print_value("Failed EXP, output", result);
+ print_value("Failed EXP, expected", expected);
+ }
+ }
+
+ for (i = 0; i < TESTCASES2_COUNT; i++)
+ {
+ fix16_t a = testcases2[i].a;
+ fix16_t b = testcases2[i].b;
+ volatile fix16_t result;
+
+ fix16_t expected = testcases2[i].add;
+ MEASURE(add_cycles, result = fix16_add(a, b));
+ if (delta(result, expected) > max_delta)
+ {
+ print_value("Failed ADD, i", i);
+ print_value("Failed ADD, a", a);
+ print_value("Failed ADD, b", b);
+ print_value("Failed ADD, output", result);
+ print_value("Failed ADD, expected", expected);
+ }
+
+ expected = testcases2[i].sub;
+ MEASURE(sub_cycles, result = fix16_sub(a, b));
+ if (delta(result, expected) > max_delta)
+ {
+ print_value("Failed SUB, i", i);
+ print_value("Failed SUB, a", a);
+ print_value("Failed SUB, b", b);
+ print_value("Failed SUB, output", result);
+ print_value("Failed SUB, expected", expected);
+ }
+
+ expected = testcases2[i].mul;
+ MEASURE(mul_cycles, result = fix16_mul(a, b));
+ if (delta(result, expected) > max_delta)
+ {
+ print_value("Failed MUL, i", i);
+ print_value("Failed MUL, a", a);
+ print_value("Failed MUL, b", b);
+ print_value("Failed MUL, output", result);
+ print_value("Failed MUL, expected", expected);
+ }
+
+ if (b != 0)
+ {
+ expected = testcases2[i].div;
+ MEASURE(div_cycles, result = fix16_div(a, b));
+ if (delta(result, expected) > max_delta)
+ {
+ print_value("Failed DIV, i", i);
+ print_value("Failed DIV, a", a);
+ print_value("Failed DIV, b", b);
+ print_value("Failed DIV, output", result);
+ print_value("Failed DIV, expected", expected);
+ }
+ }
+ }
+
+ /* Compare with floating point performance */
+#ifndef NO_FLOAT
+ for (i = 0; i < TESTCASES1_COUNT; i++)
+ {
+ float input = fix16_to_float(testcases1[i].a);
+ volatile float result;
+ MEASURE(float_sqrtf_cycles, result = sqrtf(input));
+ MEASURE(float_expf_cycles, result = expf(input));
+ }
+
+ for (i = 0; i < TESTCASES2_COUNT; i++)
+ {
+ float a = fix16_to_float(testcases2[i].a);
+ float b = fix16_to_float(testcases2[i].b);
+ volatile float result;
+ MEASURE(float_add_cycles, result = a + b);
+ MEASURE(float_sub_cycles, result = a - b);
+ MEASURE(float_mul_cycles, result = a * b);
+
+ if (b != 0)
+ {
+ MEASURE(float_div_cycles, result = a / b);
+ }
+ }
+#endif
+
+ print("fix16_sqrt", &sqrt_cycles);
+ print("float sqrtf", &float_sqrtf_cycles);
+ print("fix16_exp", &exp_cycles);
+ print("float expf", &float_expf_cycles);
+ print("fix16_add", &add_cycles);
+ print("float add", &float_add_cycles);
+ print("fix16_sub", &sub_cycles);
+ print("float sub", &float_sub_cycles);
+ print("fix16_mul", &mul_cycles);
+ print("float mul", &float_mul_cycles);
+ print("fix16_div", &div_cycles);
+ print("float div", &float_div_cycles);
+
+ return 0;
+}