X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/db2bf4111cde36048ac66bbac58547d105bc7e80..67b5031ec6d160b5cae425466a34d1be3b211dd4:/test/bench.h diff --git a/test/bench.h b/test/bench.h index 2dbce0f..e7736c4 100644 --- a/test/bench.h +++ b/test/bench.h @@ -41,49 +41,116 @@ /*----- Data structures ---------------------------------------------------*/ struct bench_time { - unsigned f; -#define BTF_TIMEOK 1u -#define BTF_CYOK 2u -#define BTF_ANY (BTF_TIMEOK | BTF_CYOK) - kludge64 s; uint32 ns; - kludge64 cy; + unsigned f; /* flags */ +#define BTF_TIMEOK 1u /* @s@ ad @ns@ slots are value */ +#define BTF_CYOK 2u /* @cy@ slot is valid */ +#define BTF_ANY (BTF_TIMEOK | BTF_CYOK) /* some part is useful */ + kludge64 s; uint32 ns; /* real time in seconds and nanos */ + kludge64 cy; /* count of CPU cycles */ }; struct bench_timing { - unsigned f; - double n, t, cy; + unsigned f; /* flags (as in @struct bench_time@) */ + double n, t, cy; /* count, time, and cycles */ }; struct bench_timer { const struct bench_timerops *ops; }; struct bench_timerops { void (*now)(struct bench_timer */*bt*/, struct bench_time */*t_out*/); + /* Fill in @*t_out@ with the current time. v*/ + void (*destroy)(struct bench_timer */*bt*/); + /* Release the timer and any resources it holds. */ }; struct bench_state { - struct bench_timer *tm; - double target_s; - unsigned f; - struct { double m, c; } clk, cy; + struct bench_timer *tm; /* a timer */ + double target_s; /* target time to run benchmarks */ + unsigned f; /* flags (@BTF_...@) for calibrations */ + struct { double m, c; } clk, cy; /* calculated overheads */ }; -typedef void bench_fn(unsigned long /*n*/, void */*p*/); +typedef void bench_fn(unsigned long /*n*/, void */*ctx*/); +/* Run the benchmark @n@ times, given a context pointer @ctx@. */ /*----- Functions provided ------------------------------------------------*/ +/* --- @bench_createtimer@ --- * + * + * Arguments: --- + * + * Returns: A freshly constructed standard timer object. + * + * Use: Allocate a timer. Dispose of it by calling + * @tm->ops->destroy(tm)@ when you're done. + */ + extern struct bench_timer *bench_createtimer(void); +/* --- @bench_init@ --- * + * + * Arguments: @struct bench_state *b@ = bench state to initialize + * @struct bench_timer *tm@ = timer to attach + * + * Returns: --- + * + * Use: Initialize the benchmark state. It still needs to be + * calibrated (use @bench_calibrate@) before it can be used, but + * this will be done automatically by @bench_measure@ if it's + * not done by hand earlier. The timer is now owned by the + * benchmark state and will be destroyed by @bench_destroy@. + */ + extern void bench_init(struct bench_state */*b*/, struct bench_timer */*tm*/); +/* --- @bench_destroy@ --- * + * + * Arguments: @struct bench_state *b@ = bench state + * + * Returns: --- + * + * Use: Destroy the benchmark state, releasing the resources that it + * holds. + */ + extern void bench_destroy(struct bench_state */*b*/); +/* --- @bench_calibrate@ --- * + * + * Arguments: @struct bench_state *b@ = bench state + * + * Returns: Zero on success, @-1@ if calibration failed. + * + * Use: Calibrate the benchmark state, so that it can be used to + * measure performance reasonably accurately. + */ + extern int bench_calibrate(struct bench_state */*b*/); +/* --- @bench_measure@ --- * + * + * Arguments: @struct bench_timing *t_out@ = where to leave the timing + * @struct bench_state *b@ = benchmark state + * @double base@ = number of internal units per call + * @bench_fn *fn@, @void *ctx@ = benchmark function to run + * + * Returns: Zero on success, @-1@ if timing failed. + * + * Use: Measure a function. The function @fn@ is called adaptively + * with an iteration count @n@ set so as to run for + * approximately @b->target_s@ seconds. + * + * The result is left in @*t_out@, with @t_out->n@ counting the + * final product of the iteration count and @base@ (which might, + * e.g., reflect the number of inner iterations the function + * performs, or the number of bytes it processes per iteration). + */ + extern int bench_measure(struct bench_timing */*t_out*/, struct bench_state */*b*/, - double /*base*/, bench_fn */*fn*/, void */*p*/); + double /*base*/, bench_fn */*fn*/, void */*ctx*/); /*----- That's all, folks -------------------------------------------------*/