From b0f99d149bd530d5265b14b16ab08b0016203996 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Wed, 28 Oct 2026 15:03:49 -0700 Subject: [PATCH 1/3] chore(quest): claim quest/m0/nightly/paired-shared.md Quest-Claim: a78669a90b5a29cc From 12c80a06b1eb8494750edecd11833cf2bcc34fed Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Wed, 28 Oct 2026 15:39:29 -0700 Subject: [PATCH 2/3] perf(net): skip the clock and grace on an unchanged miss probe Every catalog subscriber probes its misses on each poll. Since #6921 the unchanged fast path read the wall clock and locked the subscriptions for the arrival grace before deciding nothing changed, about 1,070 extra instructions per pending poll. That is the nightly's catalog fanout regression: +22.6% at one track and sixteen readers by instruction count. Read the grace only when a deferred gap could move, and the clock only when one could be due. Every fanout shape now counts at or below 22808bbb2f. Co-Authored-By: Claude Opus 5.5 --- quest/m0/nightly/README.md | 1 - quest/m0/nightly/paired-shared.md | 20 ------ rs/moq-net/src/model/track/miss.rs | 111 +++++++++++++++++++++++++---- 3 files changed, 96 insertions(+), 36 deletions(-) delete mode 100644 quest/m0/nightly/paired-shared.md diff --git a/quest/m0/nightly/README.md b/quest/m0/nightly/README.md index 22bfd31dfb1..e5c76156f5e 100644 --- a/quest/m0/nightly/README.md +++ b/quest/m0/nightly/README.md @@ -39,7 +39,6 @@ Public API: none. Wire: none. - [A Firefox late join reaches live playback](/quest/m0/nightly/firefox-late-join.md) - a Firefox player joining a live broadcast catches up within the media harness's derived playback deadline - [A stitched restart signals every TS discontinuity](/quest/m0/nightly/stitch-discontinuity.md) - a restarted publisher exported with stitching signals the program break on every affected PID - [Resolve the paired network microbenchmark regressions](/quest/m0/nightly/paired-net.md) - the reported network microbenchmark regressions are attributed and genuine extra costs are fixed with paired measurements -- [Resolve the paired catalog fanout regressions](/quest/m0/nightly/paired-shared.md) - the reported catalog fanout regressions are attributed and genuine extra costs are fixed with paired measurements - [Resolve the paired relay-session regressions](/quest/m0/nightly/paired-relay.md) - the reported relay-session regressions are attributed and genuine extra costs are fixed with paired measurements - [Probing beside Cubic](/quest/m0/nightly/competing-cubic.md) - the `competing_cubic` probe test stays within its deadline budget - [Gate stops hanging](/quest/m0/nightly/gate-hang.md) - `just gate` finishes instead of hanging to the timeout, and a hang names its module diff --git a/quest/m0/nightly/paired-shared.md b/quest/m0/nightly/paired-shared.md deleted file mode 100644 index 5163d0aacaf..00000000000 --- a/quest/m0/nightly/paired-shared.md +++ /dev/null @@ -1,20 +0,0 @@ -# [M] Resolve the paired catalog fanout regressions - -## Goal - -The reported catalog fanout regressions are attributed and genuine extra costs are fixed with paired measurements. - -## Plan - -[Rust shared bench targets](https://github.com/moq-dev/moq/actions/runs/40698329026/job/122851001460) compares -`270395a337` against `22808bbb2f` and flags four catalog-estimate fanout cases: -Hang one track/four readers +11.2%, one track/sixteen readers +20.1%, four -tracks/sixteen readers +12.2%, and MSF references one track/sixteen readers -+16.4%. The `bench-rust-shared` artifact retains paired samples. - -Determine whether the cost is production work, a changed workload, or an -invalid comparison. Fix genuine regressions and measure the publisher and -subscriber axes rather than only one fanout point. Coordinate comparison -calibration with [bench CI](/quest/m1/bench-ci.md). - -Public API: none expected. Wire: none expected. diff --git a/rs/moq-net/src/model/track/miss.rs b/rs/moq-net/src/model/track/miss.rs index 8b7e4c6bbd6..bbfd010a812 100644 --- a/rs/moq-net/src/model/track/miss.rs +++ b/rs/moq-net/src/model/track/miss.rs @@ -377,27 +377,37 @@ impl Misses { state.start_sequence, state.drops_revision, ); - let now = state.cache.pool().now_wall(); - let grace = state.arrival_grace(); let ended = state.abort.is_some() || state.is_complete(); - let terms = self.at.is_none_or(|previous| { - previous.1 != at.1 || previous.2 != at.2 || previous.4 != at.4 || previous.5 != at.5 || at.0 < previous.0 - }) || self.budget != Some(drift.budget) - || self.grace != Some(grace) - || self.ended != ended; let ledger = state.arrivals.changes(); let drops = &state.drops_changes; - if !terms - && self.at == Some(at) + // Every reader probes on every poll, mostly with nothing changed since the last, so + // that answer costs neither the subscriptions' lock nor a clock read. + let unchanged = self.at == Some(at) + && self.budget == Some(drift.budget) + && self.ended == ended && self.ledger_revision == ledger.revision() - && self.drops_revision == drops.revision() - && self.deferred.deadline().is_none_or(|at| at > now) - { - if let Some(at) = self.deferred.deadline() { - state.cache.watch_wall(at, waiter); - } + && self.drops_revision == drops.revision(); + // The grace only times deferred gaps, so with none a new one has nothing to move. + // It is judged once something else changes. + if unchanged && self.deferred.runs.is_empty() { return asks; } + let grace = state.arrival_grace(); + let unchanged = unchanged && self.grace == Some(grace); + let deadline = self.deferred.deadline(); + if unchanged && deadline.is_none() { + return asks; + } + let now = state.cache.pool().now_wall(); + if unchanged && let Some(at) = deadline.filter(|at| *at > now) { + state.cache.watch_wall(at, waiter); + return asks; + } + let terms = self.at.is_none_or(|previous| { + previous.1 != at.1 || previous.2 != at.2 || previous.4 != at.4 || previous.5 != at.5 || at.0 < previous.0 + }) || self.budget != Some(drift.budget) + || self.grace != Some(grace) + || self.ended != ended; let low = state.live_floor.unwrap_or(0).max(key.0); let top = newest.min(u64::MAX - 1); let mut candidates = RangeSet::new(); @@ -1050,6 +1060,77 @@ mod tests { assert!(misses.deferred.runs.is_empty()); } + /// A grace change with nothing deferred has no deadline to move, so an unchanged probe + /// skips it; the next gap is still timed by the new grace. + #[moq_clock::test] + async fn a_grace_change_with_nothing_deferred_times_the_next_gap() { + let broadcast = crate::broadcast::Info::default().produce(); + let track = broadcast.create_track("grace", crate::track::Info::default()).unwrap(); + let budget = Duration::from_secs(5); + let _reader = track.subscribe(Subscription::default().with_max_delay(budget)); + for sequence in 0..3 { + track + .create_group(crate::group::Info { sequence }) + .unwrap() + .finish() + .unwrap(); + } + let mut misses = Misses::default(); + let mut given_up = Vec::new(); + let waiter = kio::Waiter::noop(); + let state = track.state.read(); + let drift = Drift { + budget, + bounded: false, + edge: state.drift_edge(&Servable::ALL), + }; + let full = |span| [span].into_iter().collect(); + assert!( + misses + .judge(&state, (0, 0, None), full, &drift, &mut given_up, &waiter) + .is_empty() + ); + assert!(misses.deferred.runs.is_empty(), "a contiguous feed defers nothing"); + drop(state); + + let wider = Duration::from_secs(20); + let _wide = track.subscribe(Subscription::default().with_max_delay(wider)); + let state = track.state.read(); + assert_eq!(state.arrival_grace(), wider); + assert!( + misses + .judge( + &state, + (0, 0, None), + |_| panic!("nothing deferred: the new grace waits for a change"), + &drift, + &mut given_up, + &waiter + ) + .is_empty() + ); + drop(state); + + track + .create_group(crate::group::Info { sequence: 4 }) + .unwrap() + .finish() + .unwrap(); + let state = track.state.read(); + let opened = state.cache.pool().now_wall(); + assert!( + misses + .judge(&state, (0, 0, None), full, &drift, &mut given_up, &waiter) + .is_empty() + ); + assert_eq!(misses.deferred.overlapping(0..5).collect::>(), vec![3..4]); + assert_eq!( + misses.deferred.deadline(), + Some(opened + wider), + "timed by the new grace" + ); + } + #[test] fn deferred_splits_and_replacements_retire_the_old_age_entries() { let mut deferred = Deferred::default(); From d3eab1780ccdd34e25833111e06e3caeacf56c25 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Wed, 28 Oct 2026 21:43:23 -0700 Subject: [PATCH 3/3] test(net): pass the named floor main added to Misses::judge Co-Authored-By: Claude Opus 5.5 --- rs/moq-net/src/model/track/miss.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rs/moq-net/src/model/track/miss.rs b/rs/moq-net/src/model/track/miss.rs index 12c11dba803..6bc2dc064ec 100644 --- a/rs/moq-net/src/model/track/miss.rs +++ b/rs/moq-net/src/model/track/miss.rs @@ -1117,7 +1117,7 @@ mod tests { let full = |span| [span].into_iter().collect(); assert!( misses - .judge(&state, (0, 0, None), full, &drift, &mut given_up, &waiter) + .judge(&state, (0, 0, None), None, full, &drift, &mut given_up, &waiter) .is_empty() ); assert!(misses.deferred.runs.is_empty(), "a contiguous feed defers nothing"); @@ -1132,6 +1132,7 @@ mod tests { .judge( &state, (0, 0, None), + None, |_| panic!("nothing deferred: the new grace waits for a change"), &drift, &mut given_up, @@ -1150,7 +1151,7 @@ mod tests { let opened = state.cache.pool().now_wall(); assert!( misses - .judge(&state, (0, 0, None), full, &drift, &mut given_up, &waiter) + .judge(&state, (0, 0, None), None, full, &drift, &mut given_up, &waiter) .is_empty() ); assert_eq!(misses.deferred.overlapping(0..5).collect::>(), vec![3..4]);