Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4387688
chore(quest): claim quest/m1/release-perf/README.md
kixelated Oct 25, 2026
e03bf01
fix(bench): skip targets without Criterion output when pairing a base
kixelated Oct 25, 2026
fb89e97
fix(mux): keep catalog_write_order within the rendition cap
kixelated Oct 25, 2026
5ad3ef9
fix(relay): stop the auth bench waiting for a grant it already has
kixelated Oct 25, 2026
e830aec
fix(stats): stop the four-tier tick sweep below the snapshot cap
kixelated Oct 25, 2026
35d4265
docs(bench): note that pairing skips targets without Criterion samples
kixelated Oct 25, 2026
705116a
chore(quest): claim quest/m1/release-perf/README.md
kixelated Nov 5, 2026
dcdff9c
chore: merge release performance claim and preserve upstream benchmar…
kixelated Nov 5, 2026
5076da7
Merge remote-tracking branch 'origin/main' into quest/m1/release-perf…
kixelated Nov 5, 2026
eaf569d
feat(bench): repeat paired relay workloads without Criterion
kixelated Nov 5, 2026
d1e7150
quest: record release pairing blocked by pending shell fix
kixelated Nov 5, 2026
81f0161
fix(bench): validate relay-only mode and clarify retained context
kixelated Nov 5, 2026
94a08b9
fix(bench): record initial host load before building
kixelated Nov 5, 2026
c5087c4
Merge remote-tracking branch 'origin/main' into quest/m1/release-perf…
kixelated Nov 5, 2026
56d7989
quest: resume release pairing after shell fix landed
kixelated Nov 5, 2026
56cd80b
perf: complete release fanout pairing and preserve accepted costs
kixelated Nov 5, 2026
223d37c
style(bench): format retained release evidence
kixelated Nov 5, 2026
ec20fc2
docs(bench): disclose every manual host-load reading
kixelated Nov 5, 2026
919bb14
chore: merge main and preserve completed performance evidence
kixelated Nov 6, 2026
e47af1b
docs(quest): clear completed release performance blocker
kixelated Nov 6, 2026
fb019cc
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Nov 6, 2026
7a67dc7
docs(quest): remove stale release performance prose
kixelated Nov 6, 2026
2758468
Merge remote-tracking branch 'origin/main' into pr-7986
pullfrog[bot] Nov 6, 2026
be6f5f2
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Nov 6, 2026
9966f09
test(net): quarantine the datagram-end close under load
pullfrog[bot] Nov 6, 2026
6a657f4
docs(bench): pin release comparison reproduction revisions
kixelated Nov 6, 2026
4081790
docs(quest): enable quarantined case for reproduction
kixelated Nov 6, 2026
49ab926
fix(bench): clarify completed report and relay lock holder
kixelated Nov 6, 2026
502d02d
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Nov 6, 2026
606f5f7
Merge remote-tracking branch 'origin/main' into HEAD
kixelated Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/relay-cpu-bisect.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Against `main` at [619df6e1b3](https://github.com/moq-dev/moq/commit/619df6e1b3)

`Cursor::probe` is the relay's check for groups a reader has missed. Each time a subscriber asks for its next group, the probe looks at what arrived on the track since its last look and decides whether any group the reader still wants has left the cache without the live feed delivering it (evicted, skipped, or from before the feed started), and asks upstream to fill those. A live reader that takes each group as it arrives never has such a gap, yet it paid for the whole check on every group: locking the subscription and the track's shared state, cloning the track's fills, walking the arrival ledger, checking each new group for holes, and running the ask-and-answer loop. Each time the cache aged out an old group, the eviction also landed with every reader, all of which had already taken it, and forced each one to re-run the full check. The fast path judges a group the arrival walk serves without the hole, backfill, and ledger passes, skips the subscription, fills, and answers when nothing is asked or owed, and starts each reader's eviction inbox above what it handed out. It recovers most of [moq-dev/moq#6171](https://github.com/moq-dev/moq/pull/6171)'s and [moq-dev/moq#7339](https://github.com/moq-dev/moq/pull/7339)'s cost.

kio's `WaiterList::register` was the session path's second-largest self cost: 7.2k per group. A waiter recorded 8 lists, and a relay session's control and serving tasks parked on more, so every list past the eighth took a duplicate entry on every poll. Remembering 16 cut the session by 4,424 (-3.9%) and was initially reverted after two moq-net integration tests failed. [moq-dev/moq#7789](https://github.com/moq-dev/moq/pull/7789) fixes the front's metadata/abort ordering and the quiet-catalog test's detached handshake, then raises the record limit to 16; its paired session measurement is recorded in that PR. Forcing every idle gate to walk still reproduced both failures, so the suspected idle-gate wake dependency did not explain them. The per-group costs this report attributes and nothing here cut are accepted in the [release-perf epic](../quest/m1/release-perf/README.md).
kio's `WaiterList::register` was the session path's second-largest self cost: 7.2k per group. A waiter recorded 8 lists, and a relay session's control and serving tasks parked on more, so every list past the eighth took a duplicate entry on every poll. Remembering 16 cut the session by 4,424 (-3.9%) and was initially reverted after two moq-net integration tests failed. [moq-dev/moq#7789](https://github.com/moq-dev/moq/pull/7789) fixes the front's metadata/abort ordering and the quiet-catalog test's detached handshake, then raises the record limit to 16; its paired session measurement is recorded in that PR. Forcing every idle gate to walk still reproduced both failures, so the suspected idle-gate wake dependency did not explain them. The per-group costs this report attributes and nothing here cut are accepted in the [release performance report](release-perf.md).

On the quiet test host (run.we4umM, one-minute load at most 4.7), chat over io\_uring went from 154.5k \[154.1-155.0] instructions per frame on `main` to 148.9k \[148.3-150.8] with the probe and window changes (-3.6%), four rounds each, every cell at 20,000 frames/s with no loss. The relay's QUIC, crypto, and syscalls are most of its cost, so the model's -23% shows as a few percent there.

Expand All @@ -127,7 +127,7 @@ On the quiet test host (run.we4umM, one-minute load at most 4.7), chat over io\_
Neither cost is in the probe's judgement, so the fast path left both in place:

- **[moq-dev/moq#6995](https://github.com/moq-dev/moq/pull/6995), the live index's walk.** It indexed the live feed's groups apart from fetched backfill, so every search for live content (`TrackState::live`) walked a chain of two flattened options where it had walked the cache's range. The walk's callers are the drift edge each read measures (`poll_drift` → `drift_edge` → `live_edge`) and the arrival walk, on the reader's cursor and its forward-drop cursor alike; the judgement never calls it. It still cost 2,840 inclusive per group on `main`, as at [moq-dev/moq#7542](https://github.com/moq-dev/moq/pull/7542)'s merge (2,817). The probe's own share of the PR (+1,115 self) did fall with the fast path: the probe's self cost went from 4,343 at the merge to 1,842 on `main`.
- **[moq-dev/moq#7542](https://github.com/moq-dev/moq/pull/7542), layered window queries.** A window answers each query from its shared fixed runs and a layer of moving ones (`runs::Layered::first` and `last`): +3,810 inclusive at the merge, less about 800 in the range-map queries they replaced. [moq-dev/moq#7605](https://github.com/moq-dev/moq/pull/7605)'s single-set fast path brought them to 2,117 on `main`, about 40 queries per delivery at about 50 instructions each, from the forward-drop walk, peeks, admission, and the probe. That is the number of window queries a per-reader window answers, not a walk, so it is accepted in the [release-perf epic](../quest/m1/release-perf/README.md).
- **[moq-dev/moq#7542](https://github.com/moq-dev/moq/pull/7542), layered window queries.** A window answers each query from its shared fixed runs and a layer of moving ones (`runs::Layered::first` and `last`): +3,810 inclusive at the merge, less about 800 in the range-map queries they replaced. [moq-dev/moq#7605](https://github.com/moq-dev/moq/pull/7605)'s single-set fast path brought them to 2,117 on `main`, about 40 queries per delivery at about 50 instructions each, from the forward-drop walk, peeks, admission, and the probe. That is the number of window queries a per-reader window answers, not a walk, so it is accepted in the [release performance report](release-perf.md).

`TrackState::live` now walks either the cache or the live index through one branch per call, and the drift edge's single-run search scans it statically rather than through a `dyn` iterator (run.m71Z8E, against `main` at [fa9c1bf2a7](https://github.com/moq-dev/moq/commit/fa9c1bf2a7)):

Expand Down Expand Up @@ -178,7 +178,7 @@ Each change is counted against the row above in its own run (N037x9, vS3CAR, DV1
- **The budget.** A read that blocks before its group's first frame judges the group's expiry. `Consumer::poll_expiry` asked the logical reader's budget (`Recover::poll_budget`: the reader's lock and a sync of its mirrored preferences) before `is_expired`, which answers false without the budget until a group lands above. The sync is redundant there: a preference update mirrors into every copy at once (`Mirror::sync`), a route change syncs every reader (`serve_from`), and the landing that makes the budget matter wakes the read through `watch_landing`, which then asks the budget. `is_expired` now takes the `Recover` and asks only past that check.
- **The forward drop.** The relay's track side polls the reader for runs to report (`TrackRun::poll_forward_drop`) on each track wake, and again after a receive that parked, to collect a stale skip the receive's probe queued without a wake. Each poll judged every copy (`Reader::let_go`) with nothing to report, and the second probed the live edge again (`Cursor::poll_drift` and `probe`) right after the receive had, with the same waiter. The reader now returns once nothing is queued, and the second poll only collects. Drop probes fall from 5 to 3 per delivered group.

What remains of each viewer's live read is accepted in the [release-perf epic](../quest/m1/release-perf/README.md): about 3.5k per delivered group in the drop poll's probe and 3.5k in the receive's (three each, one wake of each kind), and 0.9k in the expiry checks of a read that blocks before its first frame and of a group waiting for stream credit, which park on the next landing.
What remains of each viewer's live read is accepted in the [release performance report](release-perf.md): about 3.5k per delivered group in the drop poll's probe and 3.5k in the receive's (three each, one wake of each kind), and 0.9k in the expiry checks of a read that blocks before its first frame and of a group waiting for stream credit, which park on the next landing.

## `group_relay_frames` since `e7a5c10`

Expand Down
Loading
Loading