@@@ fltfmt mess
[mLib] / test / tvec-bench.h
CommitLineData
b1a20bee
MW
1/* -*-c-*-
2 *
3 * Test-vector framework benchmark extension
4 *
5 * (c) 2024 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28#ifndef MLIB_TVEC_BENCH_H
29#define MLIB_TVEC_BENCH_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#ifndef MLIB_BENCH_H
38# include "bench.h"
39#endif
40
41#ifndef MLIB_CONTROL_H
42# include "control.h"
43#endif
44
45#ifndef MLIB_GPRINTF_H
46# include "gprintf.h"
47#endif
48
49#ifndef MLIB_TVEC_H
50# include "tvec.h"
51#endif
52
53#ifndef MLIB_TVEC_OUTPUT_H
54# include "tvec-output.h"
55#endif
56
57/*----- Test environment --------------------------------------------------*/
58
59struct tvec_benchenv {
60 /* Benchmark environment definition. */
61
62 struct tvec_env _env; /* benchmarking is an environment */
63 struct bench_state **bst; /* benchmark state anchor or null */
64 unsigned long niter; /* iterations done per unit */
65 int riter, rbuf; /* iterations and buffer registers */
66 const struct tvec_env *env; /* subordinate environment */
67};
68
69struct tvec_benchctx {
70 /* Benchmark environment context; private. */
71
72 const struct tvec_benchenv *be; /* environment configuration */
73 struct bench_state *bst; /* benchmark state */
74 double dflt_target; /* default time in seconds */
75 unsigned f; /* flags */
76#define TVBF_SETTRG 1u /* set `@target' */
77#define TVBF_SETMASK (TVBF_SETTRG)) /* mask of @TVBF_SET...@ */
78 void *subctx; /* subordinate environment context */
79};
80
81/* --- Environment implementation --- *
82 *
83 * The following special variables are supported.
84 *
85 * * %|@target|% is the (approximate) number of seconds to run the
86 * benchmark.
87 *
88 * Unrecognized variables are passed to the subordinate environment, if there
89 * is one. Other events are passed through to the subordinate environment.
90 */
91
92extern tvec_envsetupfn tvec_benchsetup;
93extern tvec_envfindvarfn tvec_benchfindvar;
94extern tvec_envbeforefn tvec_benchbefore;
95extern tvec_envrunfn tvec_benchrun;
96extern tvec_envafterfn tvec_benchafter;
97extern tvec_envteardownfn tvec_benchteardown;
98
99#define TVEC_BENCHENV \
100 { sizeof(struct tvec_benchctx), \
101 tvec_benchsetup, \
102 tvec_benchfindvar, \
103 tvec_benchbefore, \
104 tvec_benchrun, \
105 tvec_benchafter, \
106 tvec_benchteardown }
107#define TVEC_BENCHINIT TVEC_BENCHENV, &tvec_benchstate
108
109/*----- Benchmark output extension ----------------------------------------*/
110
111#define TVEC_BENCHOUTEXT "tvec-bench"
112
113struct tvec_benchoutops {
114 /* Output extension for benchmarking. The name for this extension is
115 * %|tvec-bench|%.
116 */
117
118 void (*bbench)(struct tvec_output */*o*/,
119 const char */*desc*/, unsigned /*unit*/);
120 /* Begin a benchmark. If the description @desc@ is null -- which it will
121 * be unless we're doing adhoc testing, then the output driver should
122 * label its benchmark output, e.g., by dumping the values of the input
123 * registers marked @TVRF_ID@. The @unit@ is one of the @BTU_...@
124 * constants explaining what sort of thing is being measured.
125 */
126
127 void (*ebench)(struct tvec_output */*o*/,
128 const char */*desc*/, unsigned /*unit*/,
129 const struct bench_timing */*t*/);
130 /* End a benchmark. The @unit@ argument is as for @bbench@. If @tm@ is
131 * zero then the measurement failed; otherwise @tm->n@ counts total
132 * number of things (operations or bytes, as indicated by @unit@)
133 * processed in the indicated time.
134 */
135};
136
137extern const struct tvec_benchoutops tvec_benchoutputfallback;
138 /* Fallback operations for benchmark output. The @o@ argument is a pointer
139 * to a @struct tvec_fallbackoutput@.
140 */
141
142/*----- Global variables --------------------------------------------------*/
143
144extern struct bench_state *tvec_benchstate; /* default benchmark state */
145
146/*----- Functions provided ------------------------------------------------*/
147
148/* --- @TVEC_BENCHMARK@, @TVEC_BENCHMARK_TAG@ --- *
149 *
150 * Arguments: @const char *desc@ = a description of the benchmark
151 * @struct bench_state **bst_inout@ = benchmark state (updated)
152 * @unsigned unit@ = unit being measured (@BTU_...@ code)
153 * @double base@ = number of units per external iteration
154 *
155 * Returns: ---
156 *
157 * Use:
158 */
159
160#define TVEC_BENCHMARK_DECLS \
161 struct tvec_state *_tvbench_tv; \
162 struct tvec_fallbackoutput _tvbench_fo; \
163 const struct tvec_benchoutops *_tvbench_bo; \
164 struct tvec_output *_tvbench_o; \
165 const char *_tvbench_desc; \
166 unsigned _tvbench_unit; \
167 struct bench_timing _tvbench_tm; \
168 int _tvbench_rc; \
169 BENCH_MEASURE_DECLS
170
171#define TVEC_BENCHMARK_TAG(tag, desc, tv, bst, unit, base) \
172 MC_BEFORE(tag##__tvbench_setup, { \
173 _tvbench_tv = (tv); \
174 _tvbench_bo = tvec_outputext(_tvbench_tv, &_tvbench_o, &_tvbench_fo, \
175 TVEC_BENCHOUTEXT, \
176 &tvec_benchoutputfallback); \
177 _tvbench_desc = (desc); _tvbench_unit = (unit); \
178 TVEC_BEGINTEST(_tvbench_tv); \
179 _tvbench_bo->bbench(_tvbench_o, _tvbench_desc, _tvbench_unit); \
180 }) \
181 MC_AFTER(tag##__tvbench_report, { \
182 _tvbench_bo->ebench(_tvbench_o, _tvbench_desc, _tvbench_unit, \
183 _tvbench_rc ? 0 : &_tvbench_tm); \
184 tvec_endtest(_tvbench_tv); \
185 }) \
186 BENCH_MEASURE_TAG(tag##__tvbench_measure, (bst), \
187 _tvbench_rc, &_tvbench_tm, (base))
188
189#define TVEC_BENCHMARK(desc, tv, bst, unit, base) \
190 TVEC_BENCHMARK_TAG(tvec_bench, desc, tv, bst, unit, base)
191
192/* --- @tvec_benchprep@ --- *
193 *
194 * Arguments: @struct tvec_state *tv@ = test vector state
195 * @struct bench_state **bst_inout@ = benchmark state (updated)
196 * @unsigned f@ = calibration flags
197 *
198 * Returns: Zero on success, %$-1$% on failure.
199 *
200 * Use: If @*bst_inout@ is null then allocate and initialize a fresh
201 * benchmark state with a default timer, and @*bst_inout@ is
202 * updated to point to the fresh state. The storage for the
203 * state was allocated using the test vector state's arena.
204 *
205 * If the benchmark state hasn't been calibrated, then this is
206 * done, passing @f@ to @bench_calibrate@.
207 *
208 * On failure, the test group is skipped, reporting a suitable
209 * message, and %$-1$% is returned. If a fresh benchmark state
210 * was allocated, but calibration failed, the state is
211 * %%\emph{not}%% released.
212 */
213
214extern int tvec_benchprep(struct tvec_state */*tv*/,
215 struct bench_state **/*bst_inout*/,
216 unsigned /*f*/);
217
218/* --- @tvec_benchreport@ --- *
219 *
220 * Arguments: @const struct gprintf_ops *gops@ = print operations
221 * @void *go@ = print destination
222 * @unsigned unit@ = the unit being measured (@BTU_...@)
223 * @unsigned style@ = output style (@TVSF_...@)
224 * @const struct bench_timing *t@ = the benchmark result
225 *
226 * Returns: ---
227 *
228 * Use: Formats a report about the benchmark performance. This
229 * function is intended to be called on by an output @ebench@
230 * function.
231 */
232
233extern void tvec_benchreport
234 (const struct gprintf_ops */*gops*/, void */*go*/,
235 unsigned /*unit*/, unsigned /*style*/, const struct bench_timing */*tm*/);
236
237/*----- That's all, folks -------------------------------------------------*/
238
239#ifdef __cplusplus
240 }
241#endif
242
243#endif