| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #ifndef NO_FLOAT
- #include <math.h>
- #endif
- #include <fix16.h>
- #include "interface.h"
- #include <stdio.h>
- /* 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}
- // 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()); \
- }
- #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;
- 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_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)
- {
- #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);
- }
- }
- PRINT(sqrt_cycles, "fix16_sqrt");
- PRINT(exp_cycles, "fix16_exp");
- 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);
- }
- }
- }
- 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
- 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));
- }
- PRINT(float_sqrtf_cycles, "float sqrtf");
-
- 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);
- }
- }
- 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
- return 0;
- }
|