runners: bench: Added BENCH_SIMTIME/SIMRESET/PAUSE/RESUME/etc
- BENCH_SIMTIME() => lfs3_kiwibd_simtime() - BENCH_SIMRESET() => lfs3_kiwibd_simreset() - BENCH_SIMPAUSE() => lfs3_kiwibd_simpause() - BENCH_SIMRESUME() => lfs3_kiwibd_simresume() - BENCH_RESET() => lfs3_kiwibd_simreset() + BENCH_STACK/HEAP_RESET() - BENCH_PAUSE() => lfs3_kiwibd_simpause() + BENCH_STACK/HEAP_PAUSE() - BENCH_RESUME() => lfs3_kiwibd_simresume() + BENCH_STACK/HEAP_RESUME() This does two things: 1. Adds pause/resume counters to bd counters to make it easier to exclude operations from the current bench (potentially useful for seq+disk usage). 2. Exposes bd simtime operations as BENCH_* macros, to make it a bit easier to interact with simtime without tying all the benches to kiwibd. (Not that we'll ever probably not use kiwibd, but still). Also adopted 32-bit counters for stack/heap pause state instead of a 32-bit stack. Not that either are at a risk of overflowing, but better safe than sorry.
This commit is contained in:
+137
-43
@@ -24,20 +24,6 @@
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
// some common types
|
||||
#ifndef BENCH_KIWIBD
|
||||
typedef lfs3_emubd_io_t bench_io_t;
|
||||
typedef lfs3_emubd_sio_t bench_sio_t;
|
||||
typedef lfs3_emubd_ns_t bench_ns_t;
|
||||
typedef lfs3_emubd_sns_t bench_sns_t;
|
||||
#else
|
||||
typedef lfs3_kiwibd_io_t bench_io_t;
|
||||
typedef lfs3_kiwibd_sio_t bench_sio_t;
|
||||
typedef lfs3_kiwibd_ns_t bench_ns_t;
|
||||
typedef lfs3_kiwibd_sns_t bench_sns_t;
|
||||
#endif
|
||||
|
||||
|
||||
// some helpers
|
||||
|
||||
// append to an array with amortized doubling
|
||||
@@ -625,7 +611,8 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size) {
|
||||
|
||||
// stack hooks
|
||||
#ifdef BENCH_STACK
|
||||
uint32_t bench_stack_entered = 0;
|
||||
uint32_t bench_stack_entered = false;
|
||||
uint32_t bench_stack_paused = false;
|
||||
uint8_t *bench_stack_entrance = NULL;
|
||||
size_t bench_stack_watermark = 0;
|
||||
#endif
|
||||
@@ -634,7 +621,8 @@ size_t bench_stack_watermark = 0;
|
||||
#ifdef BENCH_STACK
|
||||
__attribute__((noinline))
|
||||
void bench_stack_enter(void) {
|
||||
bench_stack_entered = 1;
|
||||
bench_stack_entered = true;
|
||||
bench_stack_paused = false;
|
||||
bench_stack_entrance = __builtin_frame_address(0);
|
||||
bench_stack_watermark = 0;
|
||||
}
|
||||
@@ -642,7 +630,14 @@ void bench_stack_enter(void) {
|
||||
|
||||
#ifdef BENCH_STACK
|
||||
void bench_stack_exit(void) {
|
||||
bench_stack_entered = 0;
|
||||
assert(bench_stack_entered);
|
||||
bench_stack_entered = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCH_STACK
|
||||
void bench_stack_reset(void) {
|
||||
bench_stack_watermark = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -650,7 +645,7 @@ void bench_stack_exit(void) {
|
||||
#ifdef BENCH_STACK
|
||||
__attribute__((noinline))
|
||||
void bench_stack_pause(void) {
|
||||
if (bench_stack_entered & 1) {
|
||||
if (bench_stack_entered && !bench_stack_paused) {
|
||||
uint8_t *current = __builtin_frame_address(0);
|
||||
|
||||
// keep track of the deepest stack
|
||||
@@ -664,14 +659,14 @@ void bench_stack_pause(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// haha, a little 32-bit stack
|
||||
bench_stack_entered <<= 1;
|
||||
bench_stack_paused += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCH_STACK
|
||||
void bench_stack_resume(void) {
|
||||
bench_stack_entered >>= 1;
|
||||
assert(bench_stack_paused);
|
||||
bench_stack_paused -= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -695,7 +690,8 @@ size_t bench_stack_current(void) {
|
||||
|
||||
// heap hooks
|
||||
#ifdef BENCH_HEAP
|
||||
uint32_t bench_heap_entered = 0;
|
||||
uint32_t bench_heap_entered = false;
|
||||
uint32_t bench_heap_paused = false;
|
||||
size_t bench_heap_current = 0;
|
||||
size_t bench_heap_watermark = 0;
|
||||
#endif
|
||||
@@ -703,7 +699,8 @@ size_t bench_heap_watermark = 0;
|
||||
// call me when entering/exiting a bench!
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_enter(void) {
|
||||
bench_heap_entered = 1;
|
||||
bench_heap_entered = true;
|
||||
bench_heap_paused = false;
|
||||
bench_heap_current = 0;
|
||||
bench_heap_watermark = 0;
|
||||
}
|
||||
@@ -711,31 +708,34 @@ void bench_heap_enter(void) {
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_exit(void) {
|
||||
bench_heap_entered = 0;
|
||||
if (bench_heap_watermark != 0) {
|
||||
fprintf(stderr, "warning: memory leak detected (%zd > 0)\n",
|
||||
bench_heap_watermark);
|
||||
}
|
||||
assert(bench_heap_entered);
|
||||
bench_heap_entered = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_reset(void) {
|
||||
bench_heap_watermark = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// call me when entering/exiting a bd op!
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_pause(void) {
|
||||
// haha, a little 32-bit stack
|
||||
bench_heap_entered <<= 1;
|
||||
bench_heap_paused += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_resume(void) {
|
||||
bench_heap_entered >>= 1;
|
||||
assert(bench_heap_paused);
|
||||
bench_heap_paused -= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_inc(size_t size) {
|
||||
if (bench_heap_entered & 1) {
|
||||
if (bench_heap_entered && !bench_heap_paused) {
|
||||
bench_heap_current += size;
|
||||
// keep track of the deepest heap
|
||||
if (bench_heap_current > bench_heap_watermark) {
|
||||
@@ -747,9 +747,8 @@ void bench_heap_inc(size_t size) {
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
void bench_heap_dec(size_t size) {
|
||||
if (bench_heap_entered & 1) {
|
||||
assert(bench_heap_current >= size);
|
||||
bench_heap_current -= size;
|
||||
if (bench_heap_entered && !bench_heap_paused) {
|
||||
bench_heap_current -= lfs3_min(size, bench_heap_current);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -885,11 +884,16 @@ static bench_record_t *bench_records;
|
||||
size_t bench_record_count;
|
||||
size_t bench_record_capacity;
|
||||
|
||||
void bench_reset(const struct lfs3_cfg *cfg) {
|
||||
void bench_init(const struct lfs3_cfg *cfg) {
|
||||
bench_cfg = cfg;
|
||||
bench_record_count = 0;
|
||||
}
|
||||
|
||||
void bench_deinit(const struct lfs3_cfg *cfg) {
|
||||
(void)cfg;
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void bench_start(const char *probe) {
|
||||
BENCH_STACK_PAUSE();
|
||||
BENCH_HEAP_PAUSE();
|
||||
@@ -1091,6 +1095,95 @@ void bench_fresult(const char *probe, uintmax_t n, double result) {
|
||||
BENCH_STACK_RESUME();
|
||||
}
|
||||
|
||||
bench_ns_t bench_simtime(void) {
|
||||
// get the current simtime
|
||||
assert(bench_cfg);
|
||||
#ifndef BENCH_KIWIBD
|
||||
// note this can error if no timings provided
|
||||
bench_sns_t simtime = lfs3_emubd_simtime(bench_cfg);
|
||||
assert(simtime >= 0);
|
||||
#else
|
||||
// note this can error if no timings provided
|
||||
bench_sns_t simtime = lfs3_kiwibd_simtime(bench_cfg);
|
||||
assert(simtime >= 0);
|
||||
#endif
|
||||
return simtime;
|
||||
}
|
||||
|
||||
void bench_simreset(void) {
|
||||
// reset bd
|
||||
#ifndef BENCH_KIWIBD
|
||||
int err = lfs3_emubd_simreset(bench_cfg);
|
||||
assert(!err);
|
||||
#else
|
||||
int err = lfs3_kiwibd_simreset(bench_cfg);
|
||||
assert(!err);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bench_simpause(void) {
|
||||
// pause bd simulation
|
||||
#ifndef BENCH_KIWIBD
|
||||
int err = lfs3_emubd_simpause(bench_cfg);
|
||||
assert(!err);
|
||||
#else
|
||||
int err = lfs3_kiwibd_simpause(bench_cfg);
|
||||
assert(!err);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bench_simresume(void) {
|
||||
// resume bd simulation
|
||||
#ifndef BENCH_KIWIBD
|
||||
int err = lfs3_emubd_simresume(bench_cfg);
|
||||
assert(!err);
|
||||
#else
|
||||
int err = lfs3_kiwibd_simresume(bench_cfg);
|
||||
assert(!err);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bench_reset(void) {
|
||||
// reset bd
|
||||
bench_simreset();
|
||||
|
||||
// reset stack/heap measurements
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_reset();
|
||||
#endif
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void bench_pause(void) {
|
||||
// pause stack/heap measurements
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_pause();
|
||||
#endif
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_pause();
|
||||
#endif
|
||||
|
||||
// pause bd simulation
|
||||
bench_simpause();
|
||||
}
|
||||
|
||||
void bench_resume(void) {
|
||||
// resume bd simulation
|
||||
bench_simresume();
|
||||
|
||||
// resume stack/heap measurements
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_resume();
|
||||
#endif
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_resume();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// encode our permutation into a reusable id
|
||||
static void perm_printid(
|
||||
@@ -1868,22 +1961,23 @@ void perm_run(
|
||||
printf("running ");
|
||||
perm_printid(suite, case_);
|
||||
printf("\n");
|
||||
bench_reset(CFG);
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_enter();
|
||||
#endif
|
||||
bench_init(CFG);
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_enter();
|
||||
#endif
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_enter();
|
||||
#endif
|
||||
|
||||
case_->run(CFG);
|
||||
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_exit();
|
||||
#endif
|
||||
#ifdef BENCH_STACK
|
||||
bench_stack_exit();
|
||||
#endif
|
||||
#ifdef BENCH_HEAP
|
||||
bench_heap_exit();
|
||||
#endif
|
||||
bench_deinit(CFG);
|
||||
printf("finished ");
|
||||
perm_printid(suite, case_);
|
||||
printf("\n");
|
||||
|
||||
@@ -78,6 +78,19 @@ void bench_trace(const char *fmt, ...);
|
||||
#undef _STDIO_H
|
||||
|
||||
|
||||
// some common types
|
||||
#ifndef BENCH_KIWIBD
|
||||
typedef lfs3_emubd_io_t bench_io_t;
|
||||
typedef lfs3_emubd_sio_t bench_sio_t;
|
||||
typedef lfs3_emubd_ns_t bench_ns_t;
|
||||
typedef lfs3_emubd_sns_t bench_sns_t;
|
||||
#else
|
||||
typedef lfs3_kiwibd_io_t bench_io_t;
|
||||
typedef lfs3_kiwibd_sio_t bench_sio_t;
|
||||
typedef lfs3_kiwibd_ns_t bench_ns_t;
|
||||
typedef lfs3_kiwibd_sns_t bench_sns_t;
|
||||
#endif
|
||||
|
||||
// generated bench configurations
|
||||
struct lfs3_cfg;
|
||||
|
||||
@@ -138,6 +151,24 @@ void bench_fresult(const char *probe, uintmax_t n, double result);
|
||||
#define BENCH_RESULT(probe, n, result) bench_result(probe, n, result)
|
||||
#define BENCH_FRESULT(probe, n, result) bench_fresult(probe, n, result)
|
||||
|
||||
// extra hooks to get the current simtime, pause readed/progged/erased
|
||||
// counters, etc
|
||||
bench_ns_t bench_simtime(void);
|
||||
void bench_simreset(void);
|
||||
void bench_simpause(void);
|
||||
void bench_simresume(void);
|
||||
void bench_reset(void);
|
||||
void bench_pause(void);
|
||||
void bench_resume(void);
|
||||
|
||||
#define BENCH_SIMTIME() bench_simtime()
|
||||
#define BENCH_SIMRESET() bench_simreset()
|
||||
#define BENCH_SIMPAUSE() bench_simpause()
|
||||
#define BENCH_SIMRESUME() bench_simresume()
|
||||
#define BENCH_RESET() bench_reset()
|
||||
#define BENCH_PAUSE() bench_pause()
|
||||
#define BENCH_RESUME() bench_resume()
|
||||
|
||||
|
||||
// deterministic prng for pseudo-randomness in benches
|
||||
uint32_t bench_prng(uint32_t *state);
|
||||
@@ -155,15 +186,18 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
|
||||
// get the maximum/current stack usage for this run
|
||||
extern size_t bench_stack_watermark;
|
||||
__attribute__((noinline)) size_t bench_stack_current(void);
|
||||
void bench_stack_reset(void);
|
||||
__attribute__((noinline)) void bench_stack_pause(void);
|
||||
void bench_stack_resume(void);
|
||||
|
||||
#define BENCH_STACK_WATERMARK() bench_stack_watermark
|
||||
#define BENCH_STACK_CURRENT() bench_stack_current()
|
||||
#define BENCH_STACK_RESET() bench_stack_reset()
|
||||
#define BENCH_STACK_PAUSE() bench_stack_pause()
|
||||
#define BENCH_STACK_RESUME() bench_stack_resume()
|
||||
#else
|
||||
// stubs if not measuring stack
|
||||
#define BENCH_STACK_RESET()
|
||||
#define BENCH_STACK_PAUSE()
|
||||
#define BENCH_STACK_RESUME()
|
||||
#endif
|
||||
@@ -179,12 +213,14 @@ void bench_heap_dec(size_t size);
|
||||
|
||||
#define BENCH_HEAP_WATERMARK() bench_heap_watermark
|
||||
#define BENCH_HEAP_CURRENT() bench_heap_current
|
||||
#define BENCH_HEAP_RESET() bench_heap_reset()
|
||||
#define BENCH_HEAP_PAUSE() bench_heap_pause()
|
||||
#define BENCH_HEAP_RESUME() bench_heap_resume()
|
||||
#define BENCH_HEAP_INC(size) bench_heap_inc(size)
|
||||
#define BENCH_HEAP_DEC(size) bench_heap_dec(size)
|
||||
#else
|
||||
// stubs if not measuring heap
|
||||
#define BENCH_HEAP_RESET()
|
||||
#define BENCH_HEAP_PAUSE()
|
||||
#define BENCH_HEAP_RESUME()
|
||||
#define BENCH_HEAP_INC(size)
|
||||
|
||||
@@ -24,20 +24,6 @@
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
// some common types
|
||||
#ifndef TEST_KIWIBD
|
||||
typedef lfs3_emubd_ns_t test_ns_t;
|
||||
typedef lfs3_emubd_sns_t test_sns_t;
|
||||
typedef lfs3_emubd_powercycles_t test_powercycles_t;
|
||||
typedef lfs3_emubd_spowercycles_t test_spowercycles_t;
|
||||
#else
|
||||
typedef lfs3_kiwibd_ns_t test_ns_t;
|
||||
typedef lfs3_kiwibd_sns_t test_sns_t;
|
||||
typedef void test_powercycles_t;
|
||||
typedef void test_spowercycles_t;
|
||||
#endif
|
||||
|
||||
|
||||
// some helpers
|
||||
|
||||
// append to an array with amortized doubling
|
||||
|
||||
@@ -78,6 +78,19 @@ void test_trace(const char *fmt, ...);
|
||||
#undef _STDIO_H
|
||||
|
||||
|
||||
// some common types
|
||||
#ifndef TEST_KIWIBD
|
||||
typedef lfs3_emubd_ns_t test_ns_t;
|
||||
typedef lfs3_emubd_sns_t test_sns_t;
|
||||
typedef lfs3_emubd_powercycles_t test_powercycles_t;
|
||||
typedef lfs3_emubd_spowercycles_t test_spowercycles_t;
|
||||
#else
|
||||
typedef lfs3_kiwibd_ns_t test_ns_t;
|
||||
typedef lfs3_kiwibd_sns_t test_sns_t;
|
||||
typedef void test_powercycles_t;
|
||||
typedef void test_spowercycles_t;
|
||||
#endif
|
||||
|
||||
// generated test configurations
|
||||
struct lfs3_cfg;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user