From 8d6d6f2bbc980e45daf461f4a2cc16a013789f0b Mon Sep 17 00:00:00 2001 From: Jue Date: Thu, 3 Nov 2022 16:52:29 +0100 Subject: [PATCH] ztimer: add benchmarking tool --- tests/ztimer_ondemand_benchmark/Makefile | 26 +++++ tests/ztimer_ondemand_benchmark/README.md | 10 ++ tests/ztimer_ondemand_benchmark/main.c | 122 ++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 tests/ztimer_ondemand_benchmark/Makefile create mode 100644 tests/ztimer_ondemand_benchmark/README.md create mode 100644 tests/ztimer_ondemand_benchmark/main.c diff --git a/tests/ztimer_ondemand_benchmark/Makefile b/tests/ztimer_ondemand_benchmark/Makefile new file mode 100644 index 0000000000..b9ee66324b --- /dev/null +++ b/tests/ztimer_ondemand_benchmark/Makefile @@ -0,0 +1,26 @@ +include ../Makefile.tests_common + +# required modules +USEMODULE += ztimer +USEMODULE += ztimer_ondemand +USEMODULE += ztimer_ondemand_timer +USEMODULE += ztimer_ondemand_rtt +USEMODULE += ztimer_ondemand_rtc +FEATURES_REQUIRED = periph_timer +DEFAULT_MODULE += test_utils_interactive_sync + +# Select clock to benchmark: +# - ztimer_usec +USEMODULE += ztimer_usec +# - ztimer_msec +#USEMODULE += ztimer_msec +# - ztimer_sec +#USEMODULE += ztimer_sec + +# You may sepcify the compare timer device +#CFLAGS += '-DCOMPARE_TIMER_DEV=TIMER_DEV(2)' + +# You may sepcify the compare timer frequency +#CFLAGS += '-DCOMPARE_TIMER_FREQ=9750000' + +include $(RIOTBASE)/Makefile.include diff --git a/tests/ztimer_ondemand_benchmark/README.md b/tests/ztimer_ondemand_benchmark/README.md new file mode 100644 index 0000000000..a58933cadc --- /dev/null +++ b/tests/ztimer_ondemand_benchmark/README.md @@ -0,0 +1,10 @@ +ztimer_ondemand_benchmark +========================= + +This application measures latencies introduced by `ztimer_acquire()` and +`ztimer_release()`. Since it is directly interacting with the underlying +peripheral, you need at least two `periph_timer` instances if you're +benchmarking a ztimer clock based on `ztimer_periph_timer`. + +The application tries to select a unused timer automatically. If this selection +process fails, users may specify device and frequency in this test's Makefile. diff --git a/tests/ztimer_ondemand_benchmark/main.c b/tests/ztimer_ondemand_benchmark/main.c new file mode 100644 index 0000000000..b794435f78 --- /dev/null +++ b/tests/ztimer_ondemand_benchmark/main.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2022 SSV Software Systems GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Benchmarks ztimer_acquire() and ztimer_release() + * + * @author Juergen Fitschen + * + * @} + */ + +#include +#include +#include "ztimer.h" +#include "ztimer/config.h" +#include "periph/timer.h" +#include "periph_conf.h" + +#if IS_ACTIVE(MODULE_ZTIMER_SEC) +# define CLOCK ZTIMER_SEC +#elif IS_ACTIVE(MODULE_ZTIMER_MSEC) +# define CLOCK ZTIMER_MSEC +#elif IS_ACTIVE(MODULE_ZTIMER_USEC) +# define CLOCK ZTIMER_USEC +# define CLOCK_IS_ZTIMER_USEC +#else +# error "No ztimer clock selected!" +#endif + +#ifndef COMPARE_TIMER_DEV +# if IS_ACTIVE(MODULE_ZTIMER_PERIPH_TIMER) +# if CONFIG_ZTIMER_USEC_DEV == TIMER_DEV(0) +# define COMPARE_TIMER_DEV TIMER_DEV(1) +# else +# define COMPARE_TIMER_DEV TIMER_DEV(0) +# endif +# else +# define COMPARE_TIMER_DEV TIMER_DEV(0) +# endif +#endif + +#ifndef COMPARE_TIMER_FREQ +# define COMPARE_TIMER_FREQ 1000000U +#endif + +static inline uint32_t bench_start(uint32_t adjust) +{ + return timer_read(COMPARE_TIMER_DEV) + adjust; +} + +static inline uint32_t bench_finish(const char *name, uint32_t start) +{ + uint32_t stop = timer_read(COMPARE_TIMER_DEV); + uint32_t diff = stop - start; + if (name) { + printf(" - %s took %"PRIu32" ticks\n", name, diff); + } + return diff; +} + +static inline uint32_t bench_overhead(void) { + uint32_t start = bench_start(0); + uint32_t diff = bench_finish(NULL, start); + return diff; +} + +int main(void) +{ + uint32_t start, adjust; + uint32_t first_acquire, second_acquire; + uint32_t poweron_diff; + + timer_init(COMPARE_TIMER_DEV, COMPARE_TIMER_FREQ, NULL, NULL); + + adjust = bench_overhead(); + + printf("Compare timer frequency: %"PRIu32"Hz\n", (uint32_t) COMPARE_TIMER_FREQ); + printf("Compare timer overhead: %"PRIu32" ticks (will be taken into account)\n", adjust); + + puts("---"); + + puts("Benchmarking:"); + + start = bench_start(adjust); + ztimer_acquire(CLOCK); + first_acquire = bench_finish("ztimer_acquire() on inactive clock", start); + + start = bench_start(adjust); + ztimer_acquire(CLOCK); + second_acquire = bench_finish("ztimer_acquire() on active clock", start); + + start = bench_start(adjust); + ztimer_release(CLOCK); + bench_finish("ztimer_release() with users left", start); + + start = bench_start(adjust); + ztimer_release(CLOCK); + bench_finish("ztimer_release() with no users left", start); + + puts("---"); + poweron_diff = first_acquire - second_acquire; + +#if defined(CLOCK_IS_ZTIMER_USEC) && COMPARE_TIMER_FREQ == 1000000U + printf("Add this to you board.h:\n"); + printf(" #define CONFIG_ZTIMER_USEC_ADJUST_CLOCK_START %"PRIu32"\n", poweron_diff); +#else + printf("If the ztimer clock runs with with a frequency of %"PRIu32"Hz, set\n", + (uint32_t) COMPARE_TIMER_FREQ); + printf(" clock->adjust_clock_start = %"PRIu32"\n", poweron_diff); +#endif + + return 0; +}