Skip to content

Reduce unbounded MPMC broadcast publish and receive overhead #402

Open

Description

@tisonkun

Asyncband's unbounded MPMC broadcast channel retains each value for every eligible receiver. In these comparisons the bounded peers had room for the whole batch and every receiver saw every value. The single-receiver and four-receiver rows measure different costs.

Apple M4 Max, macOS arm64, rustc 1.101.0-nightly. Each cell gives rank, elapsed time relative to Asyncband and the whole-batch median over 10 interleaved runs. Lower is faster. Ecosystem measurements

Scenario Fixed rounds Asyncband Tokio async-broadcast
Publish and try-receive once 9,100,000 #3, 1.00× (300 ms) #1, 0.35× (105 ms) #2, 0.77× (231 ms)
Publish and await a ready receive 8,000,000 #3, 1.00× (273 ms) #1, 0.42× (113 ms) #2, 0.79× (215 ms)
Four publishers, one receiver 810 #3, 1.00× (302 ms) #1, 0.37× (111 ms) #2, 0.78× (236 ms)
Four receivers drain the batch 500 #3, 1.00× (326 ms) #1, 0.22× (72 ms) #2, 0.84× (275 ms)

With usize, allocation counting found one 24-byte allocation per Asyncband publication and zero for Tokio's inline value. In a matched single-receiver run, Asyncband took 292 ms, Tokio with usize took 101 ms, and Tokio publishing a newly allocated Arc<usize> took 245 ms. That control isolates much of the one-receiver gap. The four-reader path also serializes cursor advancement in Backlog::receive under one lock. Its contribution to the larger gap is still unmeasured.

First contribution

Run the command below, then repeat the Tokio comparison with an Arc<usize> payload. Use one and four receiving threads to isolate cursor contention. Keep lossless retention for slow subscribers, delivery to independent subscriptions, and the ability for received values to outlive the backlog or contain a non-Clone payload.

cargo x bench --bench ecosystem -- broadcast/no-backpressure/ --repeat 10 --raw

The existing SPMC specialization work tracks a different sender contract. SPMC issue #214 · SPMC PR #317

Performance tracking issue #396

Activity

  1. rokadepiyush49-rgb commented on Nov 6, 2026

    @rokadepiyush49-rgb

    Could you assign this to me? I'd run broadcast/no-backpressure/ on an Apple M4 (10 cores, macOS 27.0.1), repeat Tokio with Arc<usize>, and use one and four receiving threads to isolate cursor contention.

    Since recv returns Arc<T>, the per-message allocation comes with the contract. Your control puts about 144 ms of the 191 ms gap there, so I'd focus on the remaining 47 ms and the four-receiver row. If that's mostly contract too, I'd document it, as #396 allows.

    I haven't run these yet. I used Claude to help me read the code.

  2. tisonkun commented on Nov 6, 2026

    @tisonkun
    MemberAuthor

    Thanks for your interest! We don't assign issues to individual contributors. Anyone is welcome to submit a PR directly for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions