Files
littlefs/runners/bench_defines.h
T
Christopher Haster fb8d5a83aa runners: Tweaked ERASE_WIDTH to prefer ERASE_SIZE over BLOCK_SIZE
Mostly for consistency with other defines. In theory this better maps to
BLOCK_SIZE as a logical multiple of the physical ERASE_SIZE, but the
lack of subblock erasing (what would that even look like?) means this
should have no affect on simulated timings.

It does change the number of erases, however, in case that is useful for
something.
2026-03-09 22:55:46 -05:00

224 lines
10 KiB
C

// littlefs bench runner defines
#ifdef BENCH_INCLUDE
#ifndef BENCH_DEFINES_H
#define BENCH_DEFINES_H
// DISK_GEOMETRY controls which simulation we use
// 0 => NOR flash (the default)
// 1 => NAND flash
#define DISK_MAP(define) \
((DISK_GEOMETRY == 0) ? NOR_##define \
: NAND_##define)
#endif
#endif
// preconfigured defines that control how benches run
#ifdef BENCH_DEFINE
// name value (overridable)
BENCH_DEFINE(DISK_SIZE, 128*1024*1024 )
BENCH_DEFINE(DISK_GEOMETRY, 0 )
// simulation mode
// 0 => full bus+buffer sim
// 1 => simple per-byte sim
BENCH_DEFINE(DISK_SIM, 0 )
BENCH_DEFINE(READ_SIZE, DISK_MAP(READ_SIZE) )
BENCH_DEFINE(PROG_SIZE, DISK_MAP(PROG_SIZE) )
BENCH_DEFINE(ERASE_SIZE, DISK_MAP(ERASE_SIZE) )
BENCH_DEFINE(BLOCK_SIZE, LFS3_MAX(ERASE_SIZE, 512) )
BENCH_DEFINE(BLOCK_COUNT, DISK_SIZE/LFS3_MAX(BLOCK_SIZE, 1) )
BENCH_DEFINE(BLOCK_RECYCLES, 100 )
BENCH_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) )
BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) )
BENCH_DEFINE(FCACHE_SIZE, 16 )
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 )
BENCH_DEFINE(GC_FLAGS, LFS3_GC_GC )
BENCH_DEFINE(GC_STEPS, 0 )
BENCH_DEFINE(GC_LOOKAHEAD_THRESH, -1 )
BENCH_DEFINE(GC_LOOKGBMAP_THRESH, -1 )
BENCH_DEFINE(GC_PREERASE_COUNT, -1 )
BENCH_DEFINE(GC_COMPACT_THRESH, 0 )
BENCH_DEFINE(SHRUB_SIZE, BLOCK_SIZE/4 )
BENCH_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/16, 512) )
BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/16 )
BENCH_DEFINE(LOOKGBMAP_THRESH, BLOCK_COUNT/4 )
// don't bother simulating erases, this may be less realistic, but
// it's certainly faster!
BENCH_DEFINE(ERASE_VALUE, -1 )
BENCH_DEFINE(READ_WIDTH, DISK_MAP(READ_WIDTH) )
BENCH_DEFINE(PROG_WIDTH, DISK_MAP(PROG_WIDTH) )
BENCH_DEFINE(ERASE_WIDTH, DISK_MAP(ERASE_WIDTH) )
BENCH_DEFINE(READ_TIMING, DISK_MAP(READ_TIMING) )
BENCH_DEFINE(PROG_TIMING, DISK_MAP(PROG_TIMING) )
BENCH_DEFINE(ERASE_TIMING, DISK_MAP(ERASE_TIMING) )
BENCH_DEFINE(READED_TIMING, DISK_MAP(READED_TIMING) )
BENCH_DEFINE(PROGGED_TIMING, DISK_MAP(PROGGED_TIMING) )
BENCH_DEFINE(ERASED_TIMING, DISK_MAP(ERASED_TIMING) )
// NOR flash (DISK_GEOMETRY=0)
//
// based on w25q64jv:
// https://www.winbond.com/resource-files/
// W25Q64JV%20RevM%2012242024%20Plus.pdf
//
// note one thing unique to NOR flash is the extreme erase cost
//
// FR=104 MHz, quad prog (9.6 ns * 8/4)
// => +~19 ns for bus (not read!)
//
// simple per-byte sim:
// readed=40ns/B fR=50 MHz, quad read (20 ns * 8/4)
// progged=1582ns/B tPP=0.4 ms, page=256 (0.4 ms / 256 + bus)
// erased=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096)
//
// less-simple bus+buffer sim:
// 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=19ns/B (bus)
// erased=0ns/B (no bus cost)
//
BENCH_DEFINE(NOR_READ_SIZE, 1 )
BENCH_DEFINE(NOR_PROG_SIZE, 1 )
BENCH_DEFINE(NOR_ERASE_SIZE, 4096 )
BENCH_DEFINE(NOR_READ_WIDTH, (DISK_SIM == 0)
? 1
: BLOCK_SIZE )
BENCH_DEFINE(NOR_PROG_WIDTH, (DISK_SIM == 0)
? LFS3_MIN(256, BLOCK_SIZE)
: BLOCK_SIZE )
BENCH_DEFINE(NOR_ERASE_WIDTH, (DISK_SIM == 0)
? LFS3_MIN(ERASE_SIZE, BLOCK_SIZE)
: BLOCK_SIZE )
BENCH_DEFINE(NOR_READ_TIMING, (DISK_SIM == 0) ? 0 : 0 )
BENCH_DEFINE(NOR_PROG_TIMING, (DISK_SIM == 0) ? 1563 : 0 )
BENCH_DEFINE(NOR_ERASE_TIMING, (DISK_SIM == 0) ? 10986 : 0 )
BENCH_DEFINE(NOR_READED_TIMING, (DISK_SIM == 0) ? 40 : 40 )
BENCH_DEFINE(NOR_PROGGED_TIMING, (DISK_SIM == 0) ? 19 : 1582 )
BENCH_DEFINE(NOR_ERASED_TIMING, (DISK_SIM == 0) ? 0 : 10986 )
// NAND flash (DISK_GEOMETRY=1)
//
// based on w25n01gv:
// https://www.winbond.com/resource-files/W25N01GV%20Rev%20R%20070323.pdf
//
// FR=104 MHz, quad read/prog (9.6 ns * 8/4)
// => +~19 ns for bus
//
// simple per-byte sim:
// readed=31ns/B tRD1=25 us, p=2048, s=512 (25 us / 2048 + bus)
// progged=141ns/B tPP=250 us, p=2048, s=512 (250 us / 2048 + bus)
// erased=15ns/B tBE=2 ms, block=131072 (2 ms / 131072)
//
// less-simple bus+buffer sim:
// 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)
//
BENCH_DEFINE(NAND_READ_SIZE, 1 )
BENCH_DEFINE(NAND_PROG_SIZE, 512 )
BENCH_DEFINE(NAND_ERASE_SIZE, 131072 )
BENCH_DEFINE(NAND_READ_WIDTH, (DISK_SIM == 0)
? LFS3_MIN(2048, BLOCK_SIZE)
: BLOCK_SIZE )
BENCH_DEFINE(NAND_PROG_WIDTH, (DISK_SIM == 0)
? LFS3_MIN(2048, BLOCK_SIZE)
: BLOCK_SIZE )
BENCH_DEFINE(NAND_ERASE_WIDTH, (DISK_SIM == 0)
? LFS3_MIN(ERASE_SIZE, BLOCK_SIZE)
: BLOCK_SIZE )
BENCH_DEFINE(NAND_READ_TIMING, (DISK_SIM == 0) ? 12 : 0 )
BENCH_DEFINE(NAND_PROG_TIMING, (DISK_SIM == 0) ? 122 : 0 )
BENCH_DEFINE(NAND_ERASE_TIMING, (DISK_SIM == 0) ? 15 : 0 )
BENCH_DEFINE(NAND_READED_TIMING, (DISK_SIM == 0) ? 19 : 31 )
BENCH_DEFINE(NAND_PROGGED_TIMING, (DISK_SIM == 0) ? 19 : 141 )
BENCH_DEFINE(NAND_ERASED_TIMING, (DISK_SIM == 0) ? 0 : 15 )
#endif
// struct lfs3_cfg definition
#ifdef BENCH_CFG
struct lfs3_cfg _cfg = {
#ifdef BENCH_CFG_CFG
BENCH_CFG_CFG
#endif
.read_size = READ_SIZE,
.prog_size = PROG_SIZE,
.block_size = BLOCK_SIZE,
.block_count = BLOCK_COUNT,
.block_recycles = BLOCK_RECYCLES,
.rcache_size = RCACHE_SIZE,
.pcache_size = PCACHE_SIZE,
.fcache_size = FCACHE_SIZE,
.lookahead_size = LOOKAHEAD_SIZE,
#ifdef LFS3_GBMAP
.gc_lookgbmap_thresh = GC_LOOKGBMAP_THRESH,
.lookgbmap_thresh = LOOKGBMAP_THRESH,
#endif
#ifdef LFS3_PREERASE
.gc_preerase_count = GC_PREERASE_COUNT,
#endif
#ifdef LFS3_GC
.gc_flags = GC_FLAGS,
.gc_steps = GC_STEPS,
#endif
.gc_lookahead_thresh = GC_LOOKAHEAD_THRESH,
.gc_compact_thresh = GC_COMPACT_THRESH,
.shrub_size = SHRUB_SIZE,
.fragment_size = FRAGMENT_SIZE,
.crystal_thresh = CRYSTAL_THRESH,
};
struct lfs3_cfg *BENCH_CFG = &_cfg;
#endif
// struct lfs3_*bd_cfg definition
#ifdef BENCH_BDCFG
#ifndef BENCH_KIWIBD
struct lfs3_emubd_cfg _bdcfg = {
#ifdef BENCH_BDCFG_CFG
BENCH_BDCFG_CFG
#endif
.erase_value = ERASE_VALUE,
.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,
.erase_cycles = ERASE_CYCLES,
.badblock_behavior = BADBLOCK_BEHAVIOR,
.powerloss_behavior = POWERLOSS_BEHAVIOR,
.seed = BD_SEED,
};
struct lfs3_emubd_cfg *BENCH_BDCFG = &_bdcfg;
#else
struct lfs3_kiwibd_cfg _bdcfg = {
#ifdef BENCH_BDCFG_CFG
BENCH_BDCFG_CFG
#endif
.erase_value = ERASE_VALUE,
.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,
};
struct lfs3_kiwibd_cfg *BENCH_BDCFG = &_bdcfg;
#endif
#endif