From f385f8f77856f435584bc21bbb400540ba001332 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Wed, 13 Nov 2024 15:22:09 -0600 Subject: [PATCH] bench: Tweaked bench.py to include cumulative measurements This was the one piece needed to be able to replace amor.py with csv.py. The missing feature in csv.py is the ability to keep track of a running-sum, but this is a bit of a hack in amor.py considering we otherwise view csv entries as unordered. We could add a running-sum to csv.py, or instead, just include a running sum as a part of our bench output. We have all the information there anyways, and if it simplifies the mess that is our csv scripts, that's a win. --- This also replaces the bench "meas", "iter", and "size" fields with the slightly simpler "m" (measurement? metric?) and "n" fields. It's up to the specific benchmark exactly how to interpret "n", but one field is sufficient for existing scripts. --- runners/bench_runner.c | 45 +++++++++++++++++---------------------- runners/bench_runner.h | 22 +++++++------------ scripts/bench.py | 48 +++++++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/runners/bench_runner.c b/runners/bench_runner.c index daeb4f73..17447147 100644 --- a/runners/bench_runner.c +++ b/runners/bench_runner.c @@ -605,9 +605,8 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size) { // bench recording state typedef struct bench_record { - const char *meas; - uintmax_t iter; - uintmax_t size; + const char *m; + uintmax_t n; lfs_emubd_io_t last_readed; lfs_emubd_io_t last_proged; lfs_emubd_io_t last_erased; @@ -623,7 +622,7 @@ void bench_reset(struct lfs_config *cfg) { bench_record_count = 0; } -void bench_start(const char *meas, uintmax_t iter, uintmax_t size) { +void bench_start(const char *m, uintmax_t n) { // measure current read/prog/erase assert(bench_cfg); lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg); @@ -639,15 +638,14 @@ void bench_start(const char *meas, uintmax_t iter, uintmax_t size) { sizeof(bench_record_t), &bench_record_count, &bench_record_capacity); - record->meas = meas; - record->iter = iter; - record->size = size; + record->m = m; + record->n = n; record->last_readed = readed; record->last_proged = proged; record->last_erased = erased; } -void bench_stop(const char *meas) { +void bench_stop(const char *m) { // measure current read/prog/erase assert(bench_cfg); lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg); @@ -659,12 +657,11 @@ void bench_stop(const char *meas) { // find our record for (size_t i = 0; i < bench_record_count; i++) { - if (strcmp(bench_records[i].meas, meas) == 0) { + if (strcmp(bench_records[i].m, m) == 0) { // print results - printf("benched %s %zd %zd %"PRIu64" %"PRIu64" %"PRIu64"\n", - bench_records[i].meas, - bench_records[i].iter, - bench_records[i].size, + printf("benched %s %zd %"PRIu64" %"PRIu64" %"PRIu64"\n", + bench_records[i].m, + bench_records[i].n, readed - bench_records[i].last_readed, proged - bench_records[i].last_proged, erased - bench_records[i].last_erased); @@ -680,28 +677,24 @@ void bench_stop(const char *meas) { // not found? fprintf(stderr, "error: bench stopped before it was started (%s)\n", - meas); + m); assert(false); exit(-1); } -void bench_result(const char *meas, uintmax_t iter, uintmax_t size, - uintmax_t result) { +void bench_result(const char *m, uintmax_t n, uintmax_t result) { // we just print these directly - printf("benched %s %zd %zd %"PRIu64"\n", - meas, - iter, - size, + printf("benched %s %zd %"PRIu64"\n", + m, + n, result); } -void bench_fresult(const char *meas, uintmax_t iter, uintmax_t size, - double result) { +void bench_fresult(const char *m, uintmax_t n, double result) { // we just print these directly - printf("benched %s %zd %zd %.6f\n", - meas, - iter, - size, + printf("benched %s %zd %.6f\n", + m, + n, result); } diff --git a/runners/bench_runner.h b/runners/bench_runner.h index 3a01eec4..b34864a2 100644 --- a/runners/bench_runner.h +++ b/runners/bench_runner.h @@ -21,24 +21,18 @@ void bench_trace(const char *fmt, ...); // BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes // through emubd -void bench_start(const char *meas, uintmax_t iter, uintmax_t size); -void bench_stop(const char *meas); +void bench_start(const char *m, uintmax_t n); +void bench_stop(const char *m); -#define BENCH_START(meas, iter, size) \ - bench_start(meas, iter, size) -#define BENCH_STOP(meas) \ - bench_stop(meas) +#define BENCH_START(m, n) bench_start(m, n) +#define BENCH_STOP(m) bench_stop(m) // BENCH_RESULT/BENCH_FRESULT allow for explicit non-io measurements -void bench_result(const char *meas, uintmax_t iter, uintmax_t size, - uintmax_t result); -void bench_fresult(const char *meas, uintmax_t iter, uintmax_t size, - double result); +void bench_result(const char *m, uintmax_t n, uintmax_t result); +void bench_fresult(const char *m, uintmax_t n, double result); -#define BENCH_RESULT(meas, iter, size, result) \ - bench_result(meas, iter, size, result) -#define BENCH_FRESULT(meas, iter, size, result) \ - bench_fresult(meas, iter, size, result) +#define BENCH_RESULT(m, n, result) bench_result(m, n, result) +#define BENCH_FRESULT(m, n, result) bench_fresult(m, n, result) // note these are indirectly included in any generated files diff --git a/scripts/bench.py b/scripts/bench.py index dd8d0ae0..aa9b1d80 100755 --- a/scripts/bench.py +++ b/scripts/bench.py @@ -1002,9 +1002,8 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): '|' '(?P[^:]+):(?P\d+):(?Passert):' ' *(?P.*)' '|' '(?Pbenched)' - ' (?P[^\s]+)' - ' (?P\d+)' - ' (?P\d+)' + ' (?P[^\s]+)' + ' (?P\d+)' '(?: (?P[\d\.]+))?' '(?: (?P[\d\.]+))?' '(?: (?P[\d\.]+))?' @@ -1038,6 +1037,9 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): last_defines = None # fetched on demand last_stdout = co.deque(maxlen=args.get('context', 5) + 1) last_assert = None + readed_ = None + proged_ = None + erased_ = None try: while True: # parse a line for state changes @@ -1068,6 +1070,9 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): last_defines = None last_stdout.clear() last_assert = None + readed_ = 0 + proged_ = 0 + erased_ = 0 elif op == 'finished': # force a failure if args.get('fail'): @@ -1090,9 +1095,8 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): if args.get('keep_going'): proc.kill() elif op == 'benched': - meas = m.group('meas') - iter = int(m.group('iter')) - size = int(m.group('size')) + m_ = m.group('m') + n_ = int(m.group('n')) # parse measurements def dat(v): if v is None: @@ -1101,9 +1105,13 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): return float(v) else: return int(v) - readed_ = dat(m.group('readed')) - proged_ = dat(m.group('proged')) - erased_ = dat(m.group('erased')) + readed__ = dat(m.group('readed')) + proged__ = dat(m.group('proged')) + erased__ = dat(m.group('erased')) + # keep track of cumulative measurements + readed_ += readed__ + proged_ += proged__ + erased_ += erased__ if output_: # fetch defines if needed, only do this at most # once per perm @@ -1116,16 +1124,18 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args): 'suite': last_suite, 'case': last_case, **last_defines, - 'meas': meas, - 'iter': iter, - 'size': size, - 'readed': readed_, - 'proged': proged_, - 'erased': erased_}) + 'm': m_, + 'n': n_, + 'readed': readed__, + 'proged': proged__, + 'erased': erased__, + 'creaded': readed_, + 'cproged': proged_, + 'cerased': erased_}) # keep track of total for summary - readed += readed_ - proged += proged_ - erased += erased_ + readed += readed__ + proged += proged__ + erased += erased__ except KeyboardInterrupt: proc.kill() raise BenchFailure(last_id, 0, list(last_stdout)) @@ -1296,7 +1306,7 @@ def run(runner, bench_ids=[], **args): if args.get('output'): output = BenchOutput(args['output'], ['suite', 'case'], - ['meas', 'iter', 'size', 'readed', 'proged', 'erased']) + ['m', 'n', 'readed', 'proged', 'erased']) # measure runtime start = time.time()