diff --git a/bd/lfs3_emubd.c b/bd/lfs3_emubd.c index b7a0b148..0f64fb59 100644 --- a/bd/lfs3_emubd.c +++ b/bd/lfs3_emubd.c @@ -437,7 +437,9 @@ int lfs3_emubd_read(const struct lfs3_cfg *cfg, lfs3_block_t block, } // track reads - bd->reads += 1; + bd->reads += (lfs3_alignup(off + size, lfs3_max(bd->cfg->read_width, 1)) + - lfs3_aligndown(off, lfs3_max(bd->cfg->read_width, 1))) + / lfs3_max(bd->cfg->read_width, 1); bd->readed += size; if (bd->cfg->read_sleep) { int err = nanosleep(&(struct timespec){ @@ -749,7 +751,9 @@ progged:; } // track progs - bd->progs += 1; + bd->progs += (lfs3_alignup(off + size, lfs3_max(bd->cfg->prog_width, 1)) + - lfs3_aligndown(off, lfs3_max(bd->cfg->prog_width, 1))) + / lfs3_max(bd->cfg->prog_width, 1); bd->progged += size; if (bd->cfg->prog_sleep) { int err = nanosleep(&(struct timespec){ @@ -1045,7 +1049,9 @@ int lfs3_emubd_erase(const struct lfs3_cfg *cfg, lfs3_block_t block) { erased:; // track erases - bd->erases += 1; + bd->erases += lfs3_alignup(cfg->block_size, + lfs3_max(bd->cfg->erase_width, 1)) + / lfs3_max(bd->cfg->erase_width, 1); bd->erased += cfg->block_size; if (bd->cfg->erase_sleep) { int err = nanosleep(&(struct timespec){ @@ -1087,9 +1093,9 @@ lfs3_emubd_sns_t lfs3_emubd_simtime(const struct lfs3_cfg *cfg) { lfs3_emubd_t *bd = cfg->context; // error if all possible timings are zero - if (bd->cfg->reads_timing == 0 - && bd->cfg->progs_timing == 0 - && bd->cfg->erases_timing == 0 + if (bd->cfg->read_timing == 0 + && bd->cfg->prog_timing == 0 + && bd->cfg->erase_timing == 0 && bd->cfg->readed_timing == 0 && bd->cfg->progged_timing == 0 && bd->cfg->erased_timing == 0) { @@ -1098,9 +1104,9 @@ lfs3_emubd_sns_t lfs3_emubd_simtime(const struct lfs3_cfg *cfg) { } lfs3_emubd_ns_t ns - = (bd->cfg->reads_timing * bd->reads) - + (bd->cfg->progs_timing * bd->progs) - + (bd->cfg->erases_timing * bd->erases) + = (bd->cfg->read_timing * bd->reads*bd->cfg->read_width) + + (bd->cfg->prog_timing * bd->progs*bd->cfg->prog_width) + + (bd->cfg->erase_timing * bd->erases*bd->cfg->erase_width) + (bd->cfg->readed_timing * bd->readed) + (bd->cfg->progged_timing * bd->progged) + (bd->cfg->erased_timing * bd->erased); diff --git a/bd/lfs3_emubd.h b/bd/lfs3_emubd.h index 56dd027a..0b3ab9fc 100644 --- a/bd/lfs3_emubd.h +++ b/bd/lfs3_emubd.h @@ -74,28 +74,46 @@ struct lfs3_emubd_cfg { // does _not_ rely on this!). int32_t erase_value; - // Simulated read transaction timing in nanoseconds, this is added - // to simtime each read call, ignoring the requested size - lfs3_emubd_ns_t reads_timing; + // Simulated read width, this is only used for simulated read timing + // and emulates the physical read hardware on the device. Defaults + // to 1 byte. + lfs3_size_t read_width; - // Simulated prog transaction timing in nanoseconds, this is added - // to simtime each prog call, ignoring the requested size - lfs3_emubd_ns_t progs_timing; + // Simulated prog width, this is only used for simulated prog timing + // and emulates the physical prog hardware on the device. Defaults + // to 1 byte. + lfs3_size_t prog_width; - // Simulated erase transaction timing in nanoseconds, this is added - // to simtime each erase call, ignoring the requested size - lfs3_emubd_ns_t erases_timing; + // Simulated erase width, this is only used for simulated erase timing + // and emulates physical erase hardware on the device. Defaults to 1 + // byte. + lfs3_size_t erase_width; - // Simulated read byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each read call. + // Simulated per-byte read timing in nanoseconds, this is added to + // simtime each read call after aligning up to the necessary number + // of read_widths to emulate the read operation. + lfs3_emubd_ns_t read_timing; + + // Simulated per-byte prog timing in nanoseconds, this is added to + // simtime each prog call after aligning up to the necessary number + // of prog_widths to emulate the prog operation. + lfs3_emubd_ns_t prog_timing; + + // Simulated per-byte erase timing in nanoseconds, this is added to + // simtime each erase call after aligning up to the necessary number + // of erase_widths to emulate the erase operation. + lfs3_emubd_ns_t erase_timing; + + // Simulated per-byte read timing in nanoseconds, this ignores + // read_width and can be used to simulate relevant bus overhead. lfs3_emubd_ns_t readed_timing; - // Simulated prog byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each prog call. + // Simulated per-byte prog timing in nanoseconds, this ignores + // prog_width and can be used to simulate relevant bus overhead. lfs3_emubd_ns_t progged_timing; - // Simulated erase byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each erase call. + // Simulated per-byte erase timing in nanoseconds, this ignores + // erase_width and can be used to simulate relevant bus overhead. lfs3_emubd_ns_t erased_timing; // Artificial read transaction delay in nanoseconds, there is no diff --git a/bd/lfs3_kiwibd.c b/bd/lfs3_kiwibd.c index bf2cf08a..af817992 100644 --- a/bd/lfs3_kiwibd.c +++ b/bd/lfs3_kiwibd.c @@ -279,7 +279,9 @@ int lfs3_kiwibd_read(const struct lfs3_cfg *cfg, lfs3_block_t block, } // track reads - bd->reads += 1; + bd->reads += (lfs3_alignup(off + size, lfs3_max(bd->cfg->read_width, 1)) + - lfs3_aligndown(off, lfs3_max(bd->cfg->read_width, 1))) + / lfs3_max(bd->cfg->read_width, 1); bd->readed += size; if (bd->cfg->read_sleep) { int err = nanosleep(&(struct timespec){ @@ -408,7 +410,9 @@ int lfs3_kiwibd_prog(const struct lfs3_cfg *cfg, lfs3_block_t block, } // track progs - bd->progs += 1; + bd->progs += (lfs3_alignup(off + size, lfs3_max(bd->cfg->prog_width, 1)) + - lfs3_aligndown(off, lfs3_max(bd->cfg->prog_width, 1))) + / lfs3_max(bd->cfg->prog_width, 1); bd->progged += size; if (bd->cfg->prog_sleep) { int err = nanosleep(&(struct timespec){ @@ -470,7 +474,9 @@ int lfs3_kiwibd_erase(const struct lfs3_cfg *cfg, lfs3_block_t block) { erased:; // track erases - bd->erases += 1; + bd->erases += lfs3_alignup(cfg->block_size, + lfs3_max(bd->cfg->erase_width, 1)) + / lfs3_max(bd->cfg->erase_width, 1); bd->erased += cfg->block_size; if (bd->cfg->erase_sleep) { int err = nanosleep(&(struct timespec){ @@ -512,9 +518,9 @@ lfs3_kiwibd_sns_t lfs3_kiwibd_simtime(const struct lfs3_cfg *cfg) { lfs3_kiwibd_t *bd = cfg->context; // error if all possible timings are zero - if (bd->cfg->reads_timing == 0 - && bd->cfg->progs_timing == 0 - && bd->cfg->erases_timing == 0 + if (bd->cfg->read_timing == 0 + && bd->cfg->prog_timing == 0 + && bd->cfg->erase_timing == 0 && bd->cfg->readed_timing == 0 && bd->cfg->progged_timing == 0 && bd->cfg->erased_timing == 0) { @@ -523,9 +529,9 @@ lfs3_kiwibd_sns_t lfs3_kiwibd_simtime(const struct lfs3_cfg *cfg) { } lfs3_kiwibd_ns_t ns - = (bd->cfg->reads_timing * bd->reads) - + (bd->cfg->progs_timing * bd->progs) - + (bd->cfg->erases_timing * bd->erases) + = (bd->cfg->read_timing * bd->reads*bd->cfg->read_width) + + (bd->cfg->prog_timing * bd->progs*bd->cfg->prog_width) + + (bd->cfg->erase_timing * bd->erases*bd->cfg->erase_width) + (bd->cfg->readed_timing * bd->readed) + (bd->cfg->progged_timing * bd->progged) + (bd->cfg->erased_timing * bd->erased); diff --git a/bd/lfs3_kiwibd.h b/bd/lfs3_kiwibd.h index f459471d..18d89131 100644 --- a/bd/lfs3_kiwibd.h +++ b/bd/lfs3_kiwibd.h @@ -43,28 +43,46 @@ struct lfs3_kiwibd_cfg { // does _not_ rely on this!). int32_t erase_value; - // Simulated read transaction timing in nanoseconds, this is added - // to simtime each read call, ignoring the requested size - lfs3_kiwibd_ns_t reads_timing; + // Simulated read width, this is only used for simulated read timing + // and emulates the physical read hardware on the device. Defaults + // to 1 byte. + lfs3_size_t read_width; - // Simulated prog transaction timing in nanoseconds, this is added - // to simtime each prog call, ignoring the requested size - lfs3_kiwibd_ns_t progs_timing; + // Simulated prog width, this is only used for simulated prog timing + // and emulates the physical prog hardware on the device. Defaults + // to 1 byte. + lfs3_size_t prog_width; - // Simulated erase transaction timing in nanoseconds, this is added - // to simtime each erase call, ignoring the requested size - lfs3_kiwibd_ns_t erases_timing; + // Simulated erase width, this is only used for simulated erase timing + // and emulates physical erase hardware on the device. Defaults to 1 + // byte. + lfs3_size_t erase_width; - // Simulated read byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each read call. + // Simulated per-byte read timing in nanoseconds, this is added to + // simtime each read call after aligning up to the necessary number + // of read_widths to emulate the read operation. + lfs3_kiwibd_ns_t read_timing; + + // Simulated per-byte prog timing in nanoseconds, this is added to + // simtime each prog call after aligning up to the necessary number + // of prog_widths to emulate the prog operation. + lfs3_kiwibd_ns_t prog_timing; + + // Simulated per-byte erase timing in nanoseconds, this is added to + // simtime each erase call after aligning up to the necessary number + // of erase_widths to emulate the erase operation. + lfs3_kiwibd_ns_t erase_timing; + + // Simulated per-byte read timing in nanoseconds, this ignores + // read_width and can be used to simulate relevant bus overhead. lfs3_kiwibd_ns_t readed_timing; - // Simulated prog byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each prog call. + // Simulated per-byte prog timing in nanoseconds, this ignores + // prog_width and can be used to simulate relevant bus overhead. lfs3_kiwibd_ns_t progged_timing; - // Simulated erase byte timing in nanoseconds, this is scaled by the - // requested size and added to simtime each erase call. + // Simulated per-byte erase timing in nanoseconds, this ignores + // erase_width and can be used to simulate relevant bus overhead. lfs3_kiwibd_ns_t erased_timing; // Artificial read transaction delay in nanoseconds, there is no diff --git a/runners/bench_defines.h b/runners/bench_defines.h index 5456d12f..1d90417e 100644 --- a/runners/bench_defines.h +++ b/runners/bench_defines.h @@ -51,30 +51,33 @@ // erased=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096) // // less-simple: - // reads=0ns (no transaction cost) - // progs=400000ns tPP=0.4 ms, page=256 - // erases=0ns (no transaction cost) + // read=0ns/B (no transaction cost) + // prog=1563ns/B tPP=0.4 ms, page=256 (0.4 ms / 256) + // erase=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096) // readed=40ns/B fR=50 MHz, quad read (20 ns * 8/4) - // progged=1484ns/B tPP=0.4 ms (((4096/256)*0.4ms - 0.4ms)/4096 + bus) - // erased=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096) - // - // note we always treat erases as per-byte to simplify benchmarking - // across different block sizes + // progged=19ns/B (bus) + // erased=0ns/B (no bus cost) // #ifdef BENCH_SIMPLE - BENCH_DEFINE(READS_TIMING, 0 ) - BENCH_DEFINE(PROGS_TIMING, 0 ) - BENCH_DEFINE(ERASES_TIMING, 0 ) + BENCH_DEFINE(READ_WIDTH, 0 ) + BENCH_DEFINE(PROG_WIDTH, 0 ) + BENCH_DEFINE(ERASE_WIDTH, 0 ) + BENCH_DEFINE(READ_TIMING, 0 ) + BENCH_DEFINE(PROG_TIMING, 0 ) + BENCH_DEFINE(ERASE_TIMING, 0 ) BENCH_DEFINE(READED_TIMING, 40 ) BENCH_DEFINE(PROGGED_TIMING, 1582 ) BENCH_DEFINE(ERASED_TIMING, 10986 ) #else - BENCH_DEFINE(READS_TIMING, 0 ) - BENCH_DEFINE(PROGS_TIMING, 400000 ) - BENCH_DEFINE(ERASES_TIMING, 0 ) + BENCH_DEFINE(READ_WIDTH, 0 ) + BENCH_DEFINE(PROG_WIDTH, 256 ) + BENCH_DEFINE(ERASE_WIDTH, BLOCK_SIZE ) + BENCH_DEFINE(READ_TIMING, 0 ) + BENCH_DEFINE(PROG_TIMING, 1563 ) + BENCH_DEFINE(ERASE_TIMING, 10986 ) BENCH_DEFINE(READED_TIMING, 40 ) - BENCH_DEFINE(PROGGED_TIMING, 1484 ) - BENCH_DEFINE(ERASED_TIMING, 10986 ) + BENCH_DEFINE(PROGGED_TIMING, 19 ) + BENCH_DEFINE(ERASED_TIMING, 0 ) #endif #else // NAND flash timings @@ -91,30 +94,33 @@ // erased=15ns/B tBE=2 ms, block=131072 (2 ms / 131072) // // less-simple: - // reads=25000ns tRD1=25 us, p=2048, s=512 - // progs=250000ns tPP=250 us, p=2048, s=512 - // erases=0ns (no transaction cost) - // readed=31ns/B tRD1=25 us (((131072/2048)*25us - 25us)/131072 + bus) - // progged=139ns/B tPP=250 us (((131072/2048)*250us - 250us)/131072 + bus) - // erased=15ns/B tBE=2 ms, block=131072 (2 ms / 131072) - // - // note we always treat erases as per-byte to simplify benchmarking - // across different block sizes + // read=12ns/B tRD1=25 us, p=2048, s=512 (25 us / 2048) + // prog=122ns/B tPP=250 us, p=2048, s=512 (250 us / 2048) + // erase=15ns/B tBE=2 ms, block=131072 (2 ms / 131072) + // readed=19ns/B (bus) + // progged=19ns/B (bus) + // erased=0ns/B (no bus cost) // #ifdef BENCH_SIMPLE - BENCH_DEFINE(READS_TIMING, 0 ) - BENCH_DEFINE(PROGS_TIMING, 0 ) - BENCH_DEFINE(ERASES_TIMING, 0 ) + BENCH_DEFINE(READ_WIDTH, 0 ) + BENCH_DEFINE(PROG_WIDTH, 0 ) + BENCH_DEFINE(ERASE_WIDTH, 0 ) + BENCH_DEFINE(READ_TIMING, 0 ) + BENCH_DEFINE(PROG_TIMING, 0 ) + BENCH_DEFINE(ERASE_TIMING, 0 ) BENCH_DEFINE(READED_TIMING, 31 ) BENCH_DEFINE(PROGGED_TIMING, 141 ) BENCH_DEFINE(ERASED_TIMING, 15 ) #else - BENCH_DEFINE(READS_TIMING, 25000 ) - BENCH_DEFINE(PROGS_TIMING, 250000 ) - BENCH_DEFINE(ERASES_TIMING, 0 ) - BENCH_DEFINE(READED_TIMING, 31 ) - BENCH_DEFINE(PROGGED_TIMING, 139 ) - BENCH_DEFINE(ERASED_TIMING, 15 ) + BENCH_DEFINE(READ_WIDTH, 2048 ) + BENCH_DEFINE(PROG_WIDTH, 2048 ) + BENCH_DEFINE(ERASE_WIDTH, BLOCK_SIZE ) + BENCH_DEFINE(READ_TIMING, 12 ) + BENCH_DEFINE(PROG_TIMING, 122 ) + BENCH_DEFINE(ERASE_TIMING, 15 ) + BENCH_DEFINE(READED_TIMING, 19 ) + BENCH_DEFINE(PROGGED_TIMING, 19 ) + BENCH_DEFINE(ERASED_TIMING, 0 ) #endif #endif #ifndef BENCH_KIWIBD @@ -170,9 +176,12 @@ BENCH_BDCFG_CFG #endif .erase_value = ERASE_VALUE, - .reads_timing = READS_TIMING, - .progs_timing = PROGS_TIMING, - .erases_timing = ERASES_TIMING, + .read_width = READ_WIDTH, + .prog_width = PROG_WIDTH, + .erase_width = ERASE_WIDTH, + .read_timing = READ_TIMING, + .prog_timing = PROG_TIMING, + .erase_timing = ERASE_TIMING, .readed_timing = READED_TIMING, .progged_timing = PROGGED_TIMING, .erased_timing = ERASED_TIMING, @@ -188,9 +197,12 @@ BENCH_BDCFG_CFG #endif .erase_value = ERASE_VALUE, - .reads_timing = READS_TIMING, - .progs_timing = PROGS_TIMING, - .erases_timing = ERASES_TIMING, + .read_width = READ_WIDTH, + .prog_width = PROG_WIDTH, + .erase_width = ERASE_WIDTH, + .read_timing = READ_TIMING, + .prog_timing = PROG_TIMING, + .erase_timing = ERASE_TIMING, .readed_timing = READED_TIMING, .progged_timing = PROGGED_TIMING, .erased_timing = ERASED_TIMING,