[Media] yring: bounded SPSC ring buffer with batched atomics

114 points event666 11 comments
[Media] yring: bounded SPSC ring buffer with batched atomics

yring is a bounded SPSC ring buffer extracted from one of my projects, where it took inproc message throughput from 3M to 17M msg/s. push() and pop() do zero atomic operations. Atomics scale with batches, not items.

Problem: Standard SPSC rings use two atomic pointers. Every push does a Release store. Every pop does a Release store. At tens/hundreds of millions of items per second, per-item atomics become the bottleneck.

Solution: Three pointers instead of two, based on ZeroMQ's ypipe. push() writes with zero atomics. flush() publishes an entire batch with one Release store. prefetch() loads all available items with one Acquire load. pop() reads with zero atomics. Then release() to free up the popped slots. No upfront batch size, no slice management. Push items one at a time, flush when you're ready.

Performance: 6-12x faster than rtrb v0.3 per-item at 32-64 byte items. Even with batch=1 on the producer, yring is 2-4x faster because the consumer naturally batches reads. rtrb's chunk API can be faster via bulk memcpy (especially at small item sizes), but requires restructuring code around upfront chunk sizes. crossbeam-channel (bounded MPMC) is 10-30x slower due to per-item CAS. Full benchmark table and chart in the README.

~550 lines including async. Three unsafe blocks. Loom-verified and Miri-clean.