iter6: revert depth bump + WRITEBACK_CHUNK_BYTES 32->8 MiB
iter5 (256-frame channel) regressed -1.8 MB/s vs iter4. Reverting to 32 frames. iter4 sample pattern shows clear ~30 s oscillation (peak 45 MB/s → dip 3 MB/s → recovery). Matches Linux vm.dirty_expire_centisecs default (30 s). 32 MiB chunks at 25 MB/s issue WAIT_AFTER every ~1.3 s, which can't outrun the kernel's own page-age limit, so pages buildup then flush in bursts. Smaller 8 MiB chunks (WAIT_AFTER every ~0.33 s) should keep the dirty-page set young and eliminate the periodic flush-burst dip.
This commit is contained in:
+1
Submodule .claude/worktrees/agent-a1cbe2cec72727536 added at f952bcfce9
+1
Submodule .claude/worktrees/agent-a82b8fb113069acd9 added at dcde016bd3
+1
Submodule .claude/worktrees/agent-ae58900dbeb230583 added at ccf7d97640
+1
Submodule .claude/worktrees/agent-aee3289bc097d110f added at 0d4879948b
+1
-10
@@ -90,16 +90,7 @@ pub const DEFAULT_PIPELINE_DEPTH: usize = 4;
|
|||||||
/// Read pipeline depth. Larger buffer compensates for drive variability
|
/// Read pipeline depth. Larger buffer compensates for drive variability
|
||||||
/// and NFS sync_file_range stalls; keeps ISO reader thread fed even when
|
/// and NFS sync_file_range stalls; keeps ISO reader thread fed even when
|
||||||
/// consumer blocks on write.
|
/// consumer blocks on write.
|
||||||
///
|
pub const READ_PIPELINE_DEPTH: usize = 32;
|
||||||
/// iter5 (2026-05-17): bumped 32 → 256 frames. autorip iter4 measured
|
|
||||||
/// dips to 2.8 MB/s with the previous 32-frame channel (~1.6 MiB at
|
|
||||||
/// ~50 KB/frame avg). When the producer thread hits any micro-stall
|
|
||||||
/// (UDF metadata cache miss, NFS RTT, decrypt key lookup), a 1.6 MiB
|
|
||||||
/// buffer drains in <100 ms and the consumer sits idle. 256 frames is
|
|
||||||
/// ~12 MiB — ~3-4 seconds of consumer drain at 4 MB/s worst-case
|
|
||||||
/// sustained output rate, enough to coast through any single-event
|
|
||||||
/// producer pause without starving the consumer.
|
|
||||||
pub const READ_PIPELINE_DEPTH: usize = 256;
|
|
||||||
|
|
||||||
/// Write pipeline depth. Smaller buffer reduces backpressure risk when
|
/// Write pipeline depth. Smaller buffer reduces backpressure risk when
|
||||||
/// sync_file_range blocks; prevents producer from accumulating too much
|
/// sync_file_range blocks; prevents producer from accumulating too much
|
||||||
|
|||||||
@@ -124,7 +124,13 @@ use super::writeback::WritebackPipeline;
|
|||||||
/// Granularity at which the Linux writeback pipeline issues
|
/// Granularity at which the Linux writeback pipeline issues
|
||||||
/// `sync_file_range` / `posix_fadvise(DONTNEED)` pairs. 32 MiB is the
|
/// `sync_file_range` / `posix_fadvise(DONTNEED)` pairs. 32 MiB is the
|
||||||
/// historical default — bounded-cache pressure stays at ~2 × this size.
|
/// historical default — bounded-cache pressure stays at ~2 × this size.
|
||||||
const WRITEBACK_CHUNK_BYTES: u64 = 32 * 1024 * 1024;
|
///
|
||||||
|
/// iter6 (2026-05-17): 32 → 8 MiB. iter4 data showed ~30 s
|
||||||
|
/// oscillation (peak 45 → dip 3 MB/s with ~30 s period) matching
|
||||||
|
/// Linux's `vm.dirty_expire_centisecs` (30 s default). Smaller chunks
|
||||||
|
/// keep dirty pages younger so the kernel flusher daemon's bursts are
|
||||||
|
/// shorter.
|
||||||
|
const WRITEBACK_CHUNK_BYTES: u64 = 8 * 1024 * 1024;
|
||||||
|
|
||||||
/// Maximum bytes outstanding in the muxer → writer-thread ring. Sized
|
/// Maximum bytes outstanding in the muxer → writer-thread ring. Sized
|
||||||
/// to cover ~4 s of muxer output at a 32 MB/s peak — enough to absorb a
|
/// to cover ~4 s of muxer output at a 32 MB/s peak — enough to absorb a
|
||||||
|
|||||||
Reference in New Issue
Block a user