Skip to content

perf(net): stream a frame's single delivery without extra allocations - #7141

Merged
kixelated merged 3 commits into
mainfrom
quest/m0/nightly/paired-relay
Oct 29, 2026
Merged

kixelated merged 3 commits into
mainfrom
quest/m0/nightly/paired-relay

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m0/nightly/paired-relay.md.

Problem

The Nightly relay session comparison (270395a337 against 22808bbb2f) flagged two lite-07-wip cases: compression with 16 publishers and 1 viewer (+14.5%), and FETCH of 256 frames of 64 bytes (+13.3%).

Attribution used load-insensitive measures: user-space instruction counts per steady round, pinned to the performance cores, and allocation counts. Each binary was built from its own export of the revision. The session bench sources are identical across the range, so the workload did not change.

  • FETCH 256 frames. Real. #6922 (fbeac8a9fd, preserve transport frame bounds) raised the per-round cost by +7.7% in instructions and +26% in allocations (3870 to 4894 per round, +4 per frame). Its parent matches base exactly. The model bench (rust/net/session_delivery_fetch_frames) regressed the same way, so the cost is in moq-net and not the relay. Each streamed frame ingest (relay and viewer) now allocated a delivery view, its content, and an Arc<Admission>. Before, it allocated one buffer.
  • Compression 16 publishers, 1 viewer. Mostly runner noise. Its three rounds read +8%, +30% and +14%. The real cost is +2.5% (relay) to +3.9% (model) in instructions per round, from the same per-frame overhead.

Approach

Nearly every frame has one delivery, so that delivery no longer pays for sharing:

  • The delivery that creates a frame's content keeps its progress in the content itself. Only a fork allocates a View, so FrameBuf is the content plus an optional fork view.
  • The admission is a producer count beside the reservation in the content's existing Publication mutex, with no Arc<Admission> and Weak of its own. Sharing is unchanged: concurrent producers of one content share one reservation, a failed one included, and the last to end releases it.
  • A whole payload freezes as itself rather than being cloned into a second OnceLock.

Allocations per round of the 256-frame FETCH are back to base (3873). Per-round instructions, lite-07-wip, 1 publisher, 1 viewer:

base 22808bbb2f head 270395a337 main this PR
model FETCH 256 frames 4.643M 5.002M (+7.7%) 4.970M 4.809M (+3.6% vs base)
relay FETCH 256 frames 4.666M 5.047M (+8.2%) 5.016M 4.847M (+3.9% vs base)
model compression 16 pub, 1 viewer 489.0k 508.0k (+3.9%) 496.0k 493.3k (+0.9% vs base)

Sweeps

These are fetch_frames (publishers 1 and 4, viewers 1 and 16, 4- and 256-frame groups) and compression (publishers 1 and 16, viewers 1 and 16), across all three versions, on the model and relay benches. In the model bench, which is deterministic, this PR lowers every case against main: 256-frame FETCH by 3.1-3.4% on lite and 1.8-1.9% on moq-transport, compression by 0.4-0.7%, and 4-frame FETCH by 0.3-0.7%. The relay sweep agrees: 256-frame FETCH drops 1.4-3.4% against main, and the 16-viewer cases are within ±1.2% or lower. Its 1-viewer cases are not deterministic, varying between runs of the same binary by up to ±20% for 4-frame FETCH and ±1.5% for compression, so those rows show nothing.

Choices made without asking

  • Charges follow the allocations. The creating delivery's view bills nothing separately, because it lives in the content and is part of CONTENT_HEAP. ADMISSION_HEAP is gone because an admission no longer allocates. The charge tests now assert this.
  • Residual cost accepted. About +3.6% of instructions remains per 256-frame lite FETCH round compared with base. It comes from fix(net): preserve transport frame bounds #6922's publication protocol: the publication mutex in admit, write_chunk and admission release, the overlap check, and the per-entry owner slot. Removing it needs a lock-free single-delivery path whose safety rests on no fork ever appearing mid-write, which the in-flight content import makes possible. I judged that not worth the risk here.

Follow-ups

  • New regression on main after this range. #7042 (6eff65506e, transport polls take kio waiters) costs +12.8% instructions per round on moq-transport-22 FETCH of 256-frame groups. That is 8.02M to 9.04M in the model bench, with its parent equal to head. Tonight's paired Nightly should flag it. This PR leaves it unaddressed, and it is worth its own quest.
  • Resolve the paired network microbenchmark regressions is investigating "group relaying" and "batched group writes" in the same range. fix(net): preserve transport frame bounds #6922 is a likely common cause there too.
  • Separate source trees that share one CARGO_TARGET_DIR produced stale cross-tree artifacts here (a moq-net bench linking another tree's lib, and kio::Bridge missing). A paired A/B harness should give each revision its own target dir.

Impact

  • Public API: none.
  • Wire: none.

Validation

  • just check: PASS, 9020 tests.
  • cargo clippy -p moq-net --all-features --all-targets -D warnings: PASS.
  • quest check --base origin/main: PASS.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 3 commits October 28, 2026 15:03
Canonical frame sharing (#6922) gave every streamed frame three heap
objects where it had one: a delivery view, its content, and a shared
admission. Nearly every frame has one delivery, so the creating
delivery's progress now lives in its content, only a fork allocates a
view, and the admission is a producer count beside the reservation in
the content's publication state. A whole payload also freezes as itself
instead of being cached a second time.

Per round of the 256-frame FETCH session bench this restores the
pre-#6922 allocation count and halves the instruction regression.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Resolve the paired relay-session regressions perf(net): stream a frame's single delivery without extra allocations Oct 29, 2026
@kixelated
kixelated marked this pull request as ready for review October 29, 2026 01:02
@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 9 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5274ccae-014c-4a01-844c-1290c386abbd
Commits

Reviewing files that changed from the base of the PR and between 53c0dcd and c560d3b.

Files selected for processing: 4
  • quest/m0/nightly/README.md
  • quest/m0/nightly/paired-relay.md
  • rs/moq-net/src/model/frame.rs
  • rs/moq-net/src/model/group.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T01:03:39.088091Z c560d3b Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed c560d3b against base 53c0dcd. No actionable bugs found in the reviewed changes.

Direction: reducing allocations inside the existing frame publication model is appropriately scoped. The creating delivery and forked views retain independent progress; admission counting remains serialized with publication, including failed reservations and last-producer release. Whole-payload freezing and group commit ownership preserve the existing sharing behavior without public API or wire changes.

Verification: static inspection of the diff, surrounding frame/group lifecycle, and relevant tests. I did not run tests, concurrency checks, or benchmarks, and did not independently reproduce the reported performance measurements.

(Written by OpenAI)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Maintainer decision: merge with the remaining ~+3.6% instructions on 256-frame lite FETCH. A lock-free single-delivery write path is being planned as a separate m2/perf follow-up quest rather than done here.

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary: no changes were needed. Head c560d3b2ac is mergeable and clean against main, and all 12 checks pass. Codex reviewed this head with no findings, and the OpenAI automated review on it also found nothing. quest check --base origin/main passes on the head. Following the maintainer's decision above, this lands with the remaining ~+3.6% instructions on 256-frame lite FETCH. The lock-free single-delivery path is planned separately.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 3e526ba Oct 29, 2026
12 checks passed
@kixelated
kixelated deleted the quest/m0/nightly/paired-relay branch October 29, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant