/* ------------------------------------------------------- benchmark.c Einfacher Geschwindigkeitstest fuer Mikrocontroller MCU : ATmega328p Takt : 19.11.2025 R. Seelig ------------------------------------------------------ */ #include #include #include #include #include #include // AVRtest: https://github.com/sprintersb/atest #include "avrtest.h" // oder: -include .../avrtest.h #define NI __attribute__((noinline,noclone)) uint32_t theCylces; static inline void start_cycles (void) { #ifdef AVRTEST_H avrtest_reset_cycles (); // Variante 2: theCylces = avrtest_cycles (); #else // Hardware-Zeugs #endif } static inline uint32_t get_cycles (void) { #ifdef AVRTEST_H return avrtest_cycles (); // Variante 2: return avrtest_cycles () - theCylces; #else // Hardware-Zeugs #endif } #define loops_int8 100000 #define loops_int16 50000 #define loops_int32 20000 #define loops_float 8000 #define n_int8 16 #define n_int16 16 #define n_int32 16 #define n_float 16 // Benchmark-Funktionen NI void benchmark_int8 (uint8_t *array) { uint8_t a, b, c, mix; for (uint32_t loop = 0; loop < loops_int8; loop++) { for (uint32_t i = 0; i < n_int8; i++) { a = array[i]; b = (a * 17) + (i ^ 0x55); c = (b * 23) ^ a; mix = a ^ (b << 1) ^ (c >> 2); mix = (mix << 3) | (mix >> 5); array[i] = mix; } } } NI void benchmark_int16 (uint16_t *array) { uint16_t a, b, c, mix; for (uint32_t loop = 0; loop < loops_int16; loop++) { for (uint32_t i = 0; i < n_int16; i++) { a = array[i]; b = (a * 123) + (i ^ 0xAAAA); c = (b * 97) ^ a; mix = a ^ (b << 1) ^ (c >> 2); mix = (mix << 3) | (mix >> 5); array[i] = mix; } } } NI void benchmark_int32 (uint32_t *array) { uint32_t a, b, c, mix; for (uint32_t loop = 0; loop < loops_int32; loop++) { for (uint32_t i = 0; i < n_int32; i++) { a = array[i]; b = (a * 12345UL) + (i ^ 0xAAAA5555UL); c = (b * 98765UL) ^ a; mix = a ^ (b << 1) ^ (c >> 2); mix = (mix << 3) | (mix >> 5); array[i] = mix; } } } NI void benchmark_float (float *array) { float a, b, c, mix; for (uint32_t loop = 0; loop < loops_float; loop++) { for (uint32_t i = 0; i < n_float; i++) { a = array[i]; b = a * 1.2345f + (float)i; c = b * 0.9876f - a; mix = a + b - c; array[i] = mix; } } } uint32_t cyc_8, cyc_16, cyc_32, cyc_float; void run_benchmark (bool verb) { uint8_t array8[n_int8]; uint16_t array16[n_int16]; uint32_t array32[n_int32]; float arrayf[n_float]; // Arrays initialisieren for (size_t i = 0; i < n_int8; i++) array8[i] = i * 3 + 1; for (size_t i = 0; i < n_int16; i++) array16[i] = i * 7 + 11; for (size_t i = 0; i < n_int32; i++) array32[i] = i * 123 + 456; for (size_t i = 0; i < n_float; i++) arrayf[i] = (float)i * 0.5f + 1.0f; // Benchmarks durchfuehren if (verb) printf ("int_8 Benchmark... "); start_cycles (); benchmark_int8 (array8); cyc_8 = get_cycles (); if (verb) printf ("done\n"); if (verb) printf ("int_16 Benchmark... "); start_cycles (); benchmark_int16 (array16); cyc_16 = get_cycles (); if (verb) printf ("done\n"); if (verb) printf ("int_32 Benchmark... "); start_cycles (); benchmark_int32 (array32); cyc_32 = get_cycles (); if (verb) printf ("done\n"); if (verb) printf ("float Benchmark... "); start_cycles (); benchmark_float (arrayf); cyc_float = get_cycles (); if (verb) printf ("done\n"); } void print_time (uint32_t mils) { uint16_t sec = mils / 1000; uint16_t ms = mils % 1000; printf ("%u.%03u", sec, ms); } void print_cycles (const char *labl, uint32_t cyc) { printf ("cycles %s: % 9" PRIu32 " = ", labl, cyc); print_time (cyc / (F_CPU / 1000)); printf (" s\n"); } void print_times (void) { const char *sep = " | "; print_time (cyc_8 / (F_CPU / 1000)); printf ("%s", sep); print_time (cyc_16 / (F_CPU / 1000)); printf ("%s", sep); print_time (cyc_32 / (F_CPU / 1000)); printf ("%s", sep); print_time (cyc_float / (F_CPU / 1000)); printf ("\n"); } /* -------------------------------------------------------- main -------------------------------------------------------- */ int main (void) { run_benchmark (false); printf ("F_CPU = %lu\n", F_CPU); if (1) { printf ("avr-gcc % 2d.%d.%d | ", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); print_times (); } else { print_cycles ("int8 ", cyc_8); print_cycles ("int16", cyc_16); print_cycles ("int32", cyc_32); print_cycles ("float", cyc_float); } return 0; }