Repository navigation
ps-st3: bulk steal transfers, and a test that reaches them - #1
Conversation
Split both ring ranges at the union of their physical wrap points and move the (at most 3) chunks with ptr::copy_nonoverlapping; small steals keep an inline scalar path, and loom falls back to the tracked per-element loop. Wraparound is exhaustively covered by new bulk steal/self-steal matrix tests. Signed-off-by: lxl66566 <lxl66566@gmail.com>
The bulk path cannot run under loom, and the reason is legitimate: loom's `UnsafeCell`
exposes no raw pointers, so `copy_nonoverlapping` is inexpressible there. The consequence is
not legitimate. Two implementations of one contract now exist, loom exercises the one that
does not ship, and nothing checks they agree, so a divergence in the bulk version would keep
a green loom run beside it.
The scalar version is now compiled under `test` as well as under loom, named
`transfer_items_scalar`, and `bulk_matches_scalar` runs both over every combination of ring
capacity, start position and count the booking step can produce, wrap points included, and
asserts the destinations are identical.
Planted and reverted, because a check that has never failed has not been shown to work.
Dropping the ordering of the two wrap points, which is wrong exactly when the destination
wraps before the source:
- let (lo, hi) = if s <= d { (s, d) } else { (d, s) };
+ let (lo, hi) = (s, d);
cargo test --release --lib
SIGBUS: access to undefined memory
cargo +nightly miri test --lib
error: Undefined Behavior: memory access failed: attempting to access 4 bytes,
but got alloc45684+0x8 which is at or beyond the end of the allocation of size 8 bytes
--> src/transfer.rs:111:17
--> src/transfer.rs:155:9
reverted: test result: ok. 1 passed
Worth recording that the native failure is a memory fault rather than an assertion: a
mis-split chunk reads out of bounds before it can produce a wrong value. So the differential
test detects, and Miri localises. Neither alone gives both.
House convention is a ps- prefix on a forked crate, so the package is ps-st3. The library keeps the name st3, so `use st3::lifo::Worker` and the `st3_loom` cfg both work against the fork with no caller churn.
Upstream's workflows were on ubuntu-latest; house runners are ubicloud. The six jobs it already had (check, test, loom, miri, lints, docs) are unchanged otherwise. Release guards on crates.io rather than on a version diff, so a re-run is a no-op and the first publish of ps-st3 does not need a bump to fire.
ff6cf40 to
2a31b4b
Compare
|
Dropped the core-local bypass slot from this branch. It is parked on Short version: single-threaded it is +21.9% on a 64-byte payload, but that needs one thread, no contention and no stealing, and it is gone under any of them. Twelve configurations across three loaded harnesses, each against a null of identical code under a second label: nine sit inside their own null, and of the three that clear it one is +3.9%, one +2.8% and one -5.5%. A real effect does not change sign with tile size. The deciding variable is task duration rather than the slot. It saves roughly one What is left here is the part that measured: upstream PR asynchronics#12 at +4.2% at 3 µs and +9.6% at 16 µs on our steal-heavy shape, and the differential test that closes the gap where loom was green against an implementation that was not the shipped one. |
Upstream's 0.4.1 plus the bulk segmented steal it has not released, which measured +4.2% at 3 us and +9.6% at 16 us on our steal-heavy shape. Patch rather than minor: no API changed, the transfer path got faster. This commit is last on the branch so the release workflow sees the version move against its parent when the branch lands.
Takes the fork to
ps-st3, and carries the two things it exists for.Upstream PR asynchronics#12, ahead of a release
"Move stolen items with bulk segmented copies." A steal moved items one at a time; this moves them as at most two
copy_nonoverlappingruns per ring, since both source and destination can wrap.Measured on the shape we actually run, one source queue and random victims:
Better than the PR's own claim of 5.5% on lifo, because our shape steals harder.
A differential test, because loom was not testing this code
cargo +nightly miri testis clean on the real bulk path, 355 s. Loom was green on 12 models but on a different implementation:transfer_itemshad a#[cfg(all(test, st3_loom))]scalar body and a#[cfg(not(all(test, st3_loom)))]bulk body, so every loom model exercised the per-element version and none of them ever ran the code the patch adds.Closed by compiling the scalar version always as
transfer_items_scalar, aliasing it under loom, and sweeping the bulk path against it across every ring capacity in {2, 4, 8, 16, 32}, every start position, and every count.The test was shown to fail before it was kept:
The rename
Package is
ps-st3; the library is stillst3, souse st3::lifo::Workerand thest3_loomcfg need no caller churn.cargo test --release: 22 + 3 + 1 pass, against 18 + 3 onmain.cargo fmtclean. Clippy 7 on this branch, 7 onmain.