diff options
author | chai <chaifix@163.com> | 2021-11-30 22:25:37 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-11-30 22:25:37 +0800 |
commit | 9e0e01b7f4375063f06e494113187d48614628e0 (patch) | |
tree | 21a4901612ad92c121f4c887a33b1bbbe87c6b00 /Client/ThirdParty/libfixmath/benchmarks/benchmark.c |
+init
Diffstat (limited to 'Client/ThirdParty/libfixmath/benchmarks/benchmark.c')
-rw-r--r-- | Client/ThirdParty/libfixmath/benchmarks/benchmark.c | 201 |
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; +} |