Skip to content

perf(mpsc): streamline unbounded buffer reclamation - #295

Merged
tisonkun merged 2 commits into
mainfrom
codex/unbounded-reclaim-outside-lock
Sep 10, 2026
Merged

perf(mpsc): streamline unbounded buffer reclamation#295
tisonkun merged 2 commits into
mainfrom
codex/unbounded-reclaim-outside-lock

Conversation

@tisonkun

@tisonkun tisonkun commented Sep 10, 2026

Copy link
Copy Markdown
Member

Summary

Unbounded receiver refills currently release retired batch allocations and oversized empty segment directories while holding the shared state mutex. Receiving also checks the last message and allocation capacity even for payload types whose segments cannot exceed the byte budget. Release retired storage after unlocking, and select oversized-payload reclamation at compile time so ordinary messages use the normal local pop path.

Make segment capacity and the retained directory's slot limit associated constants, with a named directory byte budget. Power-of-two growth keeps ordinary segments within 32 KiB; oversized payloads use one slot and release their backing allocation when consumed. A focused boundary test checks that growth, sealing, and buffer reuse preserve the capacity invariant around payload-size thresholds.

Validated with cargo x test on the default nightly and Rust 1.86.0, cargo x lint --fix, cargo x check, cargo x bench --no-run, and the full cargo x miri workflow. Benchmark adapters, extra measurement cases, and raw results are outside the repository.

Benchmarks compare main 7ad6d68d45a3b74506d9a605e594c417e80d506b with the final implementation in the same executable on an Apple M4 Max, macOS 26.6.2, rustc 1.99.0-nightly (3d6c19bb9). Values are medians of ten round medians, with randomized implementation order, 100 samples per case, 1,000 iterations per microbenchmark sample, and one batch per throughput sample. Coverage includes all 21 existing unbounded workloads, two 4,096-message inline bursts, and a 32-message burst of 64 KiB payloads. Async workloads transfer 16,384 messages per sample; inline async bursts use four runtime workers.

Workload Main This PR Elapsed change
Try round trip 10.9350 ns 10.4600 ns -4.3%
Sequential 64 B inline, 1,024 messages 10.4100 µs 8.1970 µs -21.3%
Sequential 1 KiB inline, 1,024 messages 65.6400 µs 56.6300 µs -13.7%
Sequential 1 KiB inline, 4,096 messages 265.1500 µs 226.6500 µs -14.5%
Sequential boxed 1 KiB, 1,024 messages 55.0900 µs 53.2400 µs -3.4%
Sequential 64 KiB inline, 32 messages 158.3000 µs 111.5000 µs -29.6%
Async 1 KiB, 1 producer, 1,024-message bursts 1.7685 ms 1.3835 ms -21.8%
Async 1 KiB, 8 producers, 1,024-message bursts 3.2125 ms 3.1105 ms -3.2%
Native threads, 8 producers, 16,384 messages 360.7000 µs 360.5500 µs -0.0%
Sequential usize, 1,024 messages, retained backlog 8.3330 µs 8.3740 µs +0.5%

The sequential inline/boxed payload improvements occur in all ten paired rounds. Most usize throughput workloads remain close to main; the largest measured increase versus main is 0.5% in the 1,024-message retained-backlog case. These are workload-specific measurements on this machine, not a claim of uniform improvement across platforms.

@tisonkun tisonkun changed the title perf(mpsc): release retired unbounded storage outside the lock perf(mpsc): streamline unbounded buffer reclamation Sep 10, 2026
@tisonkun
tisonkun merged commit f056962 into main Sep 10, 2026
9 checks passed
@tisonkun
tisonkun deleted the codex/unbounded-reclaim-outside-lock branch September 10, 2026 16:44
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