From 0c88e55fa8f132e8ac15426911d155f136078302 Mon Sep 17 00:00:00 2001 From: Martin Baƙinka Date: Mon, 3 May 2021 12:43:54 +0200 Subject: fixed division, undefined behaviors and some improvements (#33) * testing using ctest * emove old testing script * added github workflow CI * updated CI * added unit test for macros * F16() and F16C() are both rounding allways, so fix16_from_dbl should as well * added tests for strign operations, but these functions are in my opinion unreliable and tests are failing * removed old unittests * removed old unittests from cmake * problem with division using gcc * improved benchmark * clarification of problem with division * attempt to fix * fixed some undefined behaviors, fixed division --- benchmarks/Makefile | 4 ++-- benchmarks/benchmark.c | 45 ++++++++++++++++----------------------------- benchmarks/interface-arm.c | 4 ---- benchmarks/interface-avr.c | 5 ----- benchmarks/interface.c | 12 ++++++++++++ benchmarks/interface.h | 11 +++++++++++ benchmarks/results-avr.ods | Bin 0 -> 18676 bytes 7 files changed, 41 insertions(+), 40 deletions(-) create mode 100644 benchmarks/interface.c create mode 100644 benchmarks/results-avr.ods (limited to 'benchmarks') diff --git a/benchmarks/Makefile b/benchmarks/Makefile index 6331596..488e1a7 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -2,9 +2,9 @@ # (currently ARM Cortex M3 and AVR). They are a bit tricky to run, as they # depend on specific simulator versions. -FILES = benchmark.c ../libfixmath/fix16.c ../libfixmath/fix16_sqrt.c ../libfixmath/fix16_exp.c +FILES = benchmark.c interface.c ../libfixmath/fix16.c ../libfixmath/fix16_sqrt.c ../libfixmath/fix16_exp.c -CFLAGS = -DFIXMATH_NO_OVERFLOW -DFIXMATH_NO_ROUNDING -ffast-math -I../libfixmath +CFLAGS = -std=gnu11 -I../libfixmath .PHONY clean: rm -f *.elf diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index 70a2aeb..3942abc 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -9,15 +9,6 @@ /* Autogenerated testcases */ #include "testcases.c" -/* Tools for profiling */ - -typedef struct { - uint32_t min; - uint32_t max; - uint32_t sum; - uint32_t count; -} cyclecount_t; - // 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} @@ -40,12 +31,6 @@ static void cyclecount_update(cyclecount_t *data, uint32_t cycles) cyclecount_update(&variable, end_timing()); \ } -#define PRINT(variable, label) { \ - print_value(label " min", variable.min); \ - print_value(label " max", variable.max); \ - print_value(label " avg", variable.sum / variable.count); \ -} - static cyclecount_t exp_cycles = CYCLECOUNT_INIT; static cyclecount_t sqrt_cycles = CYCLECOUNT_INIT; static cyclecount_t add_cycles = CYCLECOUNT_INIT; @@ -53,13 +38,12 @@ static cyclecount_t sub_cycles = CYCLECOUNT_INIT; static cyclecount_t div_cycles = CYCLECOUNT_INIT; static cyclecount_t mul_cycles = CYCLECOUNT_INIT; -#ifndef NO_FLOAT 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; -#endif static fix16_t delta(fix16_t result, fix16_t expected) { @@ -119,8 +103,6 @@ int main() print_value("Failed EXP, expected", expected); } } - PRINT(sqrt_cycles, "fix16_sqrt"); - PRINT(exp_cycles, "fix16_exp"); for (i = 0; i < TESTCASES2_COUNT; i++) { @@ -175,10 +157,6 @@ int main() } } } - PRINT(add_cycles, "fix16_add"); - PRINT(sub_cycles, "fix16_sub"); - PRINT(mul_cycles, "fix16_mul"); - PRINT(div_cycles, "fix16_div"); /* Compare with floating point performance */ #ifndef NO_FLOAT @@ -187,8 +165,8 @@ int main() 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)); } - PRINT(float_sqrtf_cycles, "float sqrtf"); for (i = 0; i < TESTCASES2_COUNT; i++) { @@ -204,11 +182,20 @@ int main() MEASURE(float_div_cycles, result = a / b); } } - PRINT(float_add_cycles, "float add"); - PRINT(float_sub_cycles, "float sub"); - PRINT(float_mul_cycles, "float mul"); - PRINT(float_div_cycles, "float div"); -#endif +#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; } diff --git a/benchmarks/interface-arm.c b/benchmarks/interface-arm.c index cd37979..d0e9969 100644 --- a/benchmarks/interface-arm.c +++ b/benchmarks/interface-arm.c @@ -25,8 +25,4 @@ uint16_t end_timing() return 0x00FFFFFF - STCURRENT - 4; } -void print_value(const char *label, int32_t value) -{ - printf("%-20s %ld\n", label, value); -} diff --git a/benchmarks/interface-avr.c b/benchmarks/interface-avr.c index 02731aa..c3bd4c2 100644 --- a/benchmarks/interface-avr.c +++ b/benchmarks/interface-avr.c @@ -32,8 +32,3 @@ uint16_t end_timing() { return TCNT1 - 9; } - -void print_value(const char *label, int32_t value) -{ - printf("%-20s %ld\n", label, value); -} diff --git a/benchmarks/interface.c b/benchmarks/interface.c new file mode 100644 index 0000000..7f37648 --- /dev/null +++ b/benchmarks/interface.c @@ -0,0 +1,12 @@ +#include +#include "interface.h" + +void print_value(const char *label, int32_t value) +{ + printf("%-20s %6ld\n", label, value); +} + +void print(const char *label, cyclecount_t *count) +{ + printf("%-20s %6ld %6ld %6ld\n",label,count->min, count->sum / count->count, count->max); +} diff --git a/benchmarks/interface.h b/benchmarks/interface.h index f8c5117..cf6a3f9 100644 --- a/benchmarks/interface.h +++ b/benchmarks/interface.h @@ -3,6 +3,15 @@ #include +/* Tools for profiling */ + +typedef struct { + uint32_t min; + uint32_t max; + uint32_t sum; + uint32_t count; +} cyclecount_t; + // Initialize void interface_init(); @@ -14,3 +23,5 @@ uint16_t end_timing(); // Print a value to console, along with a descriptive label void print_value(const char *label, int32_t value); + +void print(const char *label, cyclecount_t *count); diff --git a/benchmarks/results-avr.ods b/benchmarks/results-avr.ods new file mode 100644 index 0000000..29a0894 Binary files /dev/null and b/benchmarks/results-avr.ods differ -- cgit v1.2.3