feat(causal): offcpu column + closed-books eff in the attrib probe
The probe now prints eff+offcpu next to eff — attributed plus the counted runnable off-CPU gaps over ground-truth in-site time — the per-window check that the located mechanism accounts for the whole residual (~1.00 = books closed, no remaining silent loss). Audit line gains the offcpu column, same delta-terms convention as the lib renderer. Header doc rewritten from hypothesis to resolution.
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
//! Attribution-efficiency probe (RFC 007 follow-up).
|
//! Attribution-efficiency probe (RFC 007 follow-up).
|
||||||
//!
|
//!
|
||||||
//! Hypothesis: the ~4pt impact shortfall on the 24-core validation
|
//! Original hypothesis: the ~4pt impact shortfall on the 24-core
|
||||||
//! (+29.3/+83.5 vs theoretical +33/+100) is a constant attribution
|
//! validation (+29.3/+83.5 vs theoretical +33/+100) is a constant
|
||||||
//! efficiency eff ≈ 0.91 — only ~91% of true in-target-site time is ever
|
//! attribution efficiency eff ≈ 0.91 from site-exit tail truncation.
|
||||||
//! sampled, because samples are taken only when `maybe_preempt`'s cold
|
//! The guard-drop flush closed that leak, yet eff held at ~0.93 —
|
||||||
//! block fires while in-site: the tail between the last in-site check and
|
//! RESOLVED (2026-07-13 sweep): the residual is runnable off-CPU time
|
||||||
//! `SiteGuard` drop (and any in-site time truncated by a deschedule) is
|
//! inside the site (~4.9 slice-expiry yields/entry x ~5.6µs runqueue
|
||||||
//! discarded.
|
//! wait), wall time the ground truth below counts but on-CPU
|
||||||
|
//! attribution correctly skips. The offcpu audit bucket now counts it;
|
||||||
|
//! `eff+offcpu` printed per window should sit at ~1.00 — the
|
||||||
|
//! closed-books check.
|
||||||
//!
|
//!
|
||||||
//! Measurement: same pipeline as `causal_pipeline`, but the `reserve`
|
//! Measurement: same pipeline as `causal_pipeline`, but the `reserve`
|
||||||
//! actor also measures its raw in-site time directly (rdtsc at guard
|
//! actor also measures its raw in-site time directly (rdtsc at guard
|
||||||
@@ -19,8 +22,9 @@
|
|||||||
//!
|
//!
|
||||||
//! tail_us/entry = (Δin_site − Δglobal_delay/(pct/100)) / Δentries
|
//! tail_us/entry = (Δin_site − Δglobal_delay/(pct/100)) / Δentries
|
||||||
//!
|
//!
|
||||||
//! A constant eff across 25/50% with tail/entry in the tens of µs (about
|
//! A constant eff across 25/50% with tail/entry in the tens of µs
|
||||||
//! half the causal-check cadence) confirms site-exit tail truncation.
|
//! localizes a per-entry mechanism; `eff+offcpu` ≈ 1.00 confirms the
|
||||||
|
//! runnable-gap account and rules out any remaining silent loss.
|
||||||
//!
|
//!
|
||||||
//! Run: cargo run --release --example causal_attrib_probe --features smarm-causal
|
//! Run: cargo run --release --example causal_attrib_probe --features smarm-causal
|
||||||
|
|
||||||
@@ -147,6 +151,11 @@ fn main() {
|
|||||||
|
|
||||||
let attributed = injected as f64 / (pct as f64 / 100.0);
|
let attributed = injected as f64 / (pct as f64 / 100.0);
|
||||||
let eff = attributed / in_site as f64;
|
let eff = attributed / in_site as f64;
|
||||||
|
// Books-closure check: add back the runnable off-CPU gaps the
|
||||||
|
// audit counted (delta terms -> raw via /pct) — should be ~1.00.
|
||||||
|
let eff_closed = (injected as f64 + audit.offcpu_in_site_cycles as f64)
|
||||||
|
/ (pct as f64 / 100.0)
|
||||||
|
/ in_site as f64;
|
||||||
let missing = in_site as f64 - attributed;
|
let missing = in_site as f64 - attributed;
|
||||||
let tail_us = if entries > 0 {
|
let tail_us = if entries > 0 {
|
||||||
missing / entries as f64 / hz * 1e6
|
missing / entries as f64 / hz * 1e6
|
||||||
@@ -154,7 +163,7 @@ fn main() {
|
|||||||
f64::NAN
|
f64::NAN
|
||||||
};
|
};
|
||||||
println!(
|
println!(
|
||||||
"pct {pct:>2}% in_site {:>8.1}ms attributed {:>8.1}ms eff {eff:.3} entries {entries} missing/entry {tail_us:.1}µs",
|
"pct {pct:>2}% in_site {:>8.1}ms attributed {:>8.1}ms eff {eff:.3} eff+offcpu {eff_closed:.3} entries {entries} missing/entry {tail_us:.1}µs",
|
||||||
in_site as f64 / hz * 1e3,
|
in_site as f64 / hz * 1e3,
|
||||||
attributed / hz * 1e3,
|
attributed / hz * 1e3,
|
||||||
);
|
);
|
||||||
@@ -163,13 +172,15 @@ fn main() {
|
|||||||
// missing attribution above.
|
// missing attribution above.
|
||||||
let ms = |c: u64| c as f64 / hz * 1e3;
|
let ms = |c: u64| c as f64 / hz * 1e3;
|
||||||
println!(
|
println!(
|
||||||
" audit: absorbed {:>7.1}ms forgiven {:>6.1}ms drop park {:>5.2}ms/{:<5} yield {:>5.2}ms/{:<5} discard >max {:>5.2}ms/{:<3} unarmed {}",
|
" audit: absorbed {:>7.1}ms forgiven {:>6.1}ms drop park {:>5.2}ms/{:<5} yield {:>5.2}ms/{:<5} offcpu {:>6.2}ms/{:<5} discard >max {:>5.2}ms/{:<3} unarmed {}",
|
||||||
ms(audit.spin_absorbed_cycles),
|
ms(audit.spin_absorbed_cycles),
|
||||||
ms(audit.park_forgiven_cycles),
|
ms(audit.park_forgiven_cycles),
|
||||||
ms(audit.drop_park_cycles),
|
ms(audit.drop_park_cycles),
|
||||||
audit.drop_park_n,
|
audit.drop_park_n,
|
||||||
ms(audit.drop_yield_cycles),
|
ms(audit.drop_yield_cycles),
|
||||||
audit.drop_yield_n,
|
audit.drop_yield_n,
|
||||||
|
ms(audit.offcpu_in_site_cycles),
|
||||||
|
audit.offcpu_in_site_n,
|
||||||
ms(audit.discard_overmax_cycles),
|
ms(audit.discard_overmax_cycles),
|
||||||
audit.discard_overmax_n,
|
audit.discard_overmax_n,
|
||||||
audit.discard_unarmed_n
|
audit.discard_unarmed_n
|
||||||
|
|||||||
Reference in New Issue
Block a user