Skip to content

bench: durable-write latency isolate with concurrent writers in zfs-bench - #1512

Open
gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:bench/syncwrite-mt
Open

gburd wants to merge 1 commit into
cloudius-systems:masterfrom
gburd:bench/syncwrite-mt

Conversation

@gburd

@gburd gburd commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

bench: durable-write latency isolate with concurrent writers in zfs-bench

The zfs-bench harness can measure throughput but not the per-operation cost of a durable write, which is the quantity a database's commit path actually pays. This adds a syncwrite workload that measures it directly, plus a knob to decompose it.

What it adds

  • syncwrite: a single-writer loop of pwrite + fdatasync, reporting p50 and p99 for the durable write itself.
  • threads=N: the same workload with N concurrent writers, so the per-operation cost can be observed under the contention a real commit path sees.
  • nofsync=1: a control that runs the identical loop without the fdatasync, which separates the write cost from the durability cost.

One file, scripts/bench/zfs-bench.c. No kernel code, no build-system change, no test-manifest change. It builds with the existing scripts/bench/rebuild-bench.sh line and links clean for OSv (no GLIBCXX/CXXABI/__isoc23 references, which is the constraint for loading the .so in the guest).

Why file it

This is the instrument that produced the measurements published in #1511 (the adaptive idle-spin window). That PR's table reports a busy-workload improvement and an idle-CPU comparison; without the harness in-tree a reviewer has no way to reproduce either number. Filing it makes #1511's evidence checkable rather than asserted, and gives the same decomposition (write cost vs durability cost, single vs concurrent) to anyone looking at the commit path later.

No performance claim is made here: this change only adds a measurement, it does not change any behavior.

…ench

Adds a syncwrite workload to the zfs-bench harness: a single writer issues an
8k pwrite then an fdatasync in a loop, recording per-op p50/p99, and threads=N
runs N concurrent such writers on separate files.  nofsync=1 drops the
fdatasync to separate write-completion cost from durability cost.

The single-writer form isolates the per-fsync cost with no lock contention to
attribute it to.  The concurrent form reproduces the WAL-commit-completion
serialization a database hits under load without needing a database: N writers
each fdatasync at once, and the diagnostic is whether aggregate throughput
scales with N or plateaus.  A plateau with the device and CPU both idle points
at the completion/wakeup path rather than bandwidth.

Signed-off-by: Greg Burd <greg@burd.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant