Zephyr API Documentation 4.5.0-rc1
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
benchmark.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 Måns Ansgariusson <mansgariusson@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12#ifndef ZTEST_BENCHMARK_H
13#define ZTEST_BENCHMARK_H
14#include <stdint.h>
15#include <stddef.h>
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
22/*
23 * Identifier builders for the linker-visible symbols that the ZTEST_BENCHMARK*()
24 * macros generate. Use when defining a symbol or when taking its reference.
25 */
26#define Z_ZTEST_BENCHMARK_SUITE_NODE(suite) z_ztest_benchmark_suite_##suite
27#define Z_ZTEST_BENCHMARK_NODE(suite, bench) z_ztest_benchmark_##suite##_##bench
28#define Z_ZTEST_BENCHMARK_TIMED_NODE(suite, bench) z_ztest_benchmark_timed_##suite##_##bench
29#define Z_ZTEST_BENCHMARK_MANUAL_NODE(suite, bench) z_ztest_benchmark_manual_##suite##_##bench
30#define Z_ZTEST_BENCHMARK_FN(suite, bench) z_ztest_benchmark_##suite##_##bench##_fn
31
32typedef void (*ztest_benchmark_fn_t)(void);
33struct ztest_benchmark_suite {
34 const char *name;
35 ztest_benchmark_fn_t setup;
36 ztest_benchmark_fn_t teardown;
37};
38
39struct ztest_extreme_value {
40 uint64_t value;
41 uint64_t sample;
42};
43
44struct ztest_benchmark_stats {
45 double m2;
46 double mean;
47 uint64_t total;
48 uint64_t samples;
49 struct ztest_extreme_value min;
50 struct ztest_extreme_value max;
51 /* First iteration, measured before the steady state is reached. */
52 uint64_t cold;
53};
54
55struct ztest_benchmark {
56 const char *name;
57 size_t iterations;
58 ztest_benchmark_fn_t setup;
59 ztest_benchmark_fn_t run;
60 ztest_benchmark_fn_t teardown;
61 struct ztest_benchmark_stats stats;
62 const struct ztest_benchmark_suite *suite;
63};
64
65struct ztest_benchmark_manual {
66 const char *name;
67 size_t iterations;
68 ztest_benchmark_fn_t setup;
69 ztest_benchmark_fn_t run;
70 ztest_benchmark_fn_t teardown;
71 struct ztest_benchmark_stats stats;
72 const struct ztest_benchmark_suite *suite;
73};
74
75struct ztest_benchmark_timed_stats {
76 uint64_t iterations;
77 uint64_t duration_cycles;
78};
79
80struct ztest_benchmark_timed {
81 size_t duration_ms;
82 const char *name;
83 ztest_benchmark_fn_t setup;
84 ztest_benchmark_fn_t run;
85 ztest_benchmark_fn_t teardown;
86 const struct ztest_benchmark_suite *suite;
87 struct ztest_benchmark_timed_stats stats;
88};
89
90void benchmark_main(void);
92
98
106#define ZTEST_BENCHMARK_SUITE(suite, setup_fn, teardown_fn) \
107 static const STRUCT_SECTION_ITERABLE(ztest_benchmark_suite, \
108 Z_ZTEST_BENCHMARK_SUITE_NODE(suite)) = \
109 { \
110 .name = #suite, \
111 .setup = setup_fn, \
112 .teardown = teardown_fn, \
113 }
114
124#define ZTEST_BENCHMARK(suite_name, benchmark, samples, setup_fn, teardown_fn) \
125 static __noinline void Z_ZTEST_BENCHMARK_FN(suite_name, benchmark)(void); \
126 static const STRUCT_SECTION_ITERABLE(ztest_benchmark, \
127 Z_ZTEST_BENCHMARK_NODE(suite_name, benchmark)) = \
128 { \
129 .name = #benchmark, \
130 .iterations = samples, \
131 .setup = setup_fn, \
132 .run = Z_ZTEST_BENCHMARK_FN(suite_name, benchmark), \
133 .teardown = teardown_fn, \
134 .suite = &Z_ZTEST_BENCHMARK_SUITE_NODE(suite_name), \
135 }; \
136 static __noinline void Z_ZTEST_BENCHMARK_FN(suite_name, benchmark)(void)
137
138
148#define ZTEST_BENCHMARK_TIMED(testsuite, benchmark, duration, setup_fn, teardown_fn) \
149 static __noinline void Z_ZTEST_BENCHMARK_FN(testsuite, benchmark)(void); \
150 static const STRUCT_SECTION_ITERABLE(ztest_benchmark_timed, \
151 Z_ZTEST_BENCHMARK_TIMED_NODE(testsuite, benchmark)) = \
152 { \
153 .duration_ms = duration, \
154 .name = #benchmark, \
155 .setup = setup_fn, \
156 .run = Z_ZTEST_BENCHMARK_FN(testsuite, benchmark), \
157 .teardown = teardown_fn, \
158 .suite = &Z_ZTEST_BENCHMARK_SUITE_NODE(testsuite), \
159 }; \
160 static __noinline void Z_ZTEST_BENCHMARK_FN(testsuite, benchmark)(void)
161
195#define ZTEST_BENCHMARK_MANUAL(suite_name, benchmark, samples, setup_fn, teardown_fn) \
196 static __noinline void Z_ZTEST_BENCHMARK_FN(suite_name, benchmark)(void); \
197 static STRUCT_SECTION_ITERABLE(ztest_benchmark_manual, \
198 Z_ZTEST_BENCHMARK_MANUAL_NODE(suite_name, benchmark)) = \
199 { \
200 .name = #benchmark, \
201 .iterations = samples, \
202 .setup = setup_fn, \
203 .run = Z_ZTEST_BENCHMARK_FN(suite_name, benchmark), \
204 .teardown = teardown_fn, \
205 .suite = &Z_ZTEST_BENCHMARK_SUITE_NODE(suite_name), \
206 }; \
207 static __noinline void Z_ZTEST_BENCHMARK_FN(suite_name, benchmark)(void)
208
222
234
238
239#ifdef __cplusplus
240}
241#endif
242
243#endif /* ZTEST_BENCHMARK_H */
void ztest_benchmark_start(void)
Begin the measured span of a manual benchmark iteration.
void ztest_benchmark_end(void)
End the measured span of a manual benchmark iteration.
#define min(a, b)
Return smaller value of two provided expressions.
Definition minmax.h:81
#define max(a, b)
Return larger value of two provided expressions.
Definition minmax.h:65
__UINT64_TYPE__ uint64_t
Definition stdint.h:91