Invert layout writers to push API - #9423
Conversation
Signed-off-by: Nicholas Gates <nick@nickgates.com>
Signed-off-by: Nicholas Gates <nick@nickgates.com>
Signed-off-by: Nicholas Gates <nick@nickgates.com>
Merging this PR will degrade performance by 6.91%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | cold_misaligned[(64, 256)] |
4.4 ms | 5.5 ms | -19.86% |
| ❌ | Simulation | take[small_m/shuffled/primitive/nonnull/chunks=16384/indices=16] |
1.1 ms | 1.2 ms | -11.12% |
| ⚡ | WallTime | words_gather_scalar[65536] |
9.4 µs | 8.3 µs | +13.27% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ngates/push-layout-writer (2b83616) with develop (b363fb7)
Footnotes
-
46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Signed-off-by: Nicholas Gates <nick@nickgates.com>
Polar Signals Profiling ResultsLatest Run
Powered by Polar Signals Cloud |
Summary
write,finish, andcloseSequenceIdprotocol so ordered byte sinks remain deterministic while key/value sinks may ignore orderingbuffered_bytes()Motivation
The previous public push writer fed a
SendableArrayStreaminto a background stream-based strategy tree. This made incremental writing indirect and made strategy composition and buffered-byte ownership harder to follow.The push inversion keeps one independently driven child per structural field and restores the old sequence identifiers to preserve deterministic on-disk segment ordering. Structural fan-out and finish poll sibling children concurrently, so ordered segment output does not depend on a sibling driver that is not being advanced.
Backpressure matches the previous writer's memory model: the public/root input, every structural child edge, and the segment-buffer sink each have capacity one. A slow
VortexWritefills the segment sink first, then leaf and structural mailboxes, and ultimately makes publicWriter::writeawait. Compression retains its separate, explicitly bounded CPU-concurrency window. Queued and in-flight arrays remain byte-accounted until the receiving writer has processed them.The stream compatibility adapter also explicitly drops its unused sequence pointer before finishing, preventing it from holding an ordering predecessor indefinitely.
Behavior
Writer::bytes_written()reports bytes passed to the underlyingVortexWrite.Writer::buffered_bytes()reports logical bytes retained by layout strategies and asynchronous work; it excludes output-sink buffering and allocator/statistics overhead.VortexWriteimplementations retain control over sink flushing.Performance
Release in-memory fixture: 16 numeric columns, 8 chunks, 16K rows/chunk, 16 MiB logical input. Each run used two warmups and ten measured iterations against the latest merged
develop; each value below is the median of its ten measured iterations.developrun mediansdevelop→ pushMean 1-to-8-worker scaling was 3.10x on
developand 3.65x with the push writer.Validation
cargo test -p vortex-layout -p vortex-filecargo check -p vortex-layout -p vortex-file -p vortex-cuda -p vortex-benchcargo clippy --all-targets --all-featurescargo +nightly fmt --allgit diff --checkThe layout tests include mailbox saturation/backpressure, cross-field compression overlap with deterministic segment IDs, buffered-byte accounting for queued and spawned work, nested structural ordering, dictionary codes-before-values, and zone maps after data.