Commit Graph

6 Commits

Author SHA1 Message Date
Christopher Haster 0ea11c1a0e runners: Bumped default crystal_thresh BLOCK_SIZE/8 -> BLOCK_SIZE/16
This has been adopted in external benchmarks for a while, as it manages
to push sequential write performance into a much better region of the
diminishing-returns curve.

But hey! Don't take my word for it, let's see the results from our new
bench_runner for the first time:

  NOR throughput             cs=1/8  cs=1/16
  bench_wt_seq+write        15180.0  29402.6 (+93.7%)
  bench_wt_random+write       876.2    957.3 (+9.3%)
  bench_wt_logging+write     2001.0   2153.4 (+7.6%)
  bench_wt_many+write         453.6    453.6 (+0.0%)

  NAND throughput            cs=1/8  cs=1/16
  bench_wt_seq+write        21778.7  22330.1 (+2.5%)
  bench_wt_random+write      3583.0   3637.2 (+1.5%)
  bench_wt_logging+write    10855.1  10977.1 (+1.1%)
  bench_wt_many+write          68.2     68.2 (+0.0%)

Though this doesn't really capture the tradeoffs related to file tails,
storage usage, etc.

In theory sequential writes are happy to start crystallizing as soon as
any data is written, but this leads to significant waste anytime you're
not going to write most of a block.
2026-03-09 22:51:42 -05:00
Christopher Haster 48e5cd2770 runners: Added DISK_GEOMETRY for easy multi-geometry benchmarking
So now you can easily run multiple/specific geometries without
recompiling the bench runner:

  ./scripts/bench.py -DDISK_GEOMETRY=0,1

But note by default we only simulate NOR flash. Spitting out multiple
results by default is confusing.

---

Previously this was possible by either compiling multiple bench runners
(with -DBENCH_NAND), or by explicit specifying full the geometry
(-DREAD_SIZE, -DPROG_SIZE, ..., -DREAD_TIMING, ...) at runtime, but both
were clunky and annoying to parameterize.

DISK_GEOMETRY make it easy, fits well with DISK_SIZE, and adds a field
to help identify the geometry in later scripts.

I considered filling out test_defines.h with multiple geometries as
well, but decided against it. The current idea behind test_runner is to
not test specific geometries, but to instead let individual suites/cases
iterate through the specific READ_SIZEs, PROG_SIZEs, etc, that are
relevant. Still, added DISK_GEOMETRY to test_defines.h for consistency,
but it doesn't actually control anything.
2026-03-09 22:50:51 -05:00
Christopher Haster b1d8114889 runners: Added optional BENCH/TEST_NAND geometry
Having BENCH/TEST_NAND ifdefs that enable the relevant timings, but
_not_ the relevant geometry, is certainly a choice.

Defaulting to NAND geometry when BENCH/TEST_NAND is defined is more
useful, if only for minimizing confusion.
2026-02-19 13:48:45 -06:00
Christopher Haster 4405ad47e4 runners: Reworked test/bench for out-of-tree extensions
The main changes:

- Added TEST_DEFINES and BENCH_DEFINES to allow overriding the default
  test/bench define header:

    -DTEST_DEFINES=my_test_defines.h

  Note these are VERY different from LFS_DEFINES upstream. They aren't a
  typical header file, and are included multiple times with various
  query macros.

  It's hacky, but works surprisingly well.

  Or maybe I'll just do anything to avoid having to write multiline
  macros. Ugh, backslashes.

- Moved more logic into bench/test_defines.h, including everything
  needed to integrate other filesystems out-of-tree.

  This mostly meant moving all of the cfg initialization logic into its
  own query macro (replacing the BENCH/TEST_CFG field macros).

But this also includes a bunch of small tweaks encountered while trying
to get external benchmarks running again.

The external benchmarks include several other filesystems (littlefs2,
SPIFFS, Yaffs2), and I'm hoping this injectable/queryable header thing
will do a good job at avoiding a maintenance headache. (At least a
better job than forking bench_runner.c, which was the previous
solution.)
2026-02-19 13:42:49 -06:00
Christopher Haster ab39a8fde9 runners: Adopted compile-time optional kiwibd as emubd alternative
kiwibd has been used extensively in external benchmarks, it makes sense
to make it the default bd for the bench runner:

- test_runner - defaults to emubd - more testing features
- bench_runner - defaults to kiwibd - lighter-weight disks

The benefit of kiwibd is the disk is just one big blob of RAM, so
basically no overhead. This is important when benchmarking on multi-GiB
disks.

emubd is much heavy, but as a tradeoff can do quite a bit more:
bad-block simulation, wear simulation, snapshotting, etc.

---

In theory the bd used by each runner can be controlled at compile-time
by defining -DBENCH_EMUBD, etc, but I have a feeling no one will ever
use this.
2026-02-13 13:49:32 -06:00
Christopher Haster 1b70c1f199 runners: Moved test/bench defines into test/bench_defines.h
The big TEST_IMPLICIT_DEFINES and TEST_CFG macros have been a big
pain-in-the-ass to maintain. Mostly due to C preprocessor annoyances
(bleh escaped newlines) and no-ifdef workarounds, which make a real mess
of things.

This does two things:

1. Moves all the defines out of test_runner.h and into test_defines.h
   (same for benches).

2. Inverts the include logic such that test_defines.h gets included many
   times with various "query macros" defined.

   Currently just two, but can easily add more:

   1. TEST_DEFINE(name, value) - name and default value for a define
   2. TEST_CFG(name, value) - name and value for a cfg field

   This seems to work surprisingly well. It solves all of the above C
   preprocessor issues, and provides a flexible method for defining test
   defines.

   Note an important part of making this work is that test_defines.h
   expands to an empty string by default.
2026-02-10 15:22:38 -06:00