feat(causal): ledger-audit output in the pipeline demo and attrib probe

- causal_pipeline: SMARM_CAUSAL_AUDIT=1 appends render_ledger_audit()
  after the summary; pinned summary format untouched.
- causal_attrib_probe: per-pct audit line (absorbed/forgiven/drops/
  discards) under the existing eff line, so in-site-vs-attributed and
  the loss buckets land in one place for the sweep.

1-core smoke (work + wide): books balance — absorbed = 2x injected and
forgiven = 2x injected, i.e. owed = injected x (N-1) with N=5 actors,
zero outstanding. drop park = 0 even in wide mode (the bottleneck's
queue is never empty, so its in-guard recv never parks); drop yield is
~1500 events but ~0.1ms per window, confirming slice-expiry yields
sample at their own checkpoint. Deficit decomposition needs the
parallel box.
This commit is contained in:
Claude (sandbox)
2026-07-13 12:11:24 +00:00
parent a3be8f0977
commit 9bfeb2c6a2
3 changed files with 25 additions and 0 deletions
+1
View File
@@ -4,3 +4,4 @@ smarm_trace.json
/bench_results/
__pycache__/
*.pyc
profile.coz
+18
View File
@@ -136,9 +136,11 @@ fn main() {
let g0 = smarm::causal::global_delay_cycles();
let s0 = IN_SITE_CYCLES.load(Ordering::Relaxed);
let e0 = SITE_ENTRIES.load(Ordering::Relaxed);
let a0 = smarm::causal::ledger_counters();
smarm::causal::begin_experiment_for_test("reserve", pct);
smarm::sleep(Duration::from_millis(1000));
smarm::causal::end_experiment_for_test();
let audit = smarm::causal::ledger_counters().delta_since(&a0);
let injected = smarm::causal::global_delay_cycles() - g0;
let in_site = IN_SITE_CYCLES.load(Ordering::Relaxed) - s0;
let entries = SITE_ENTRIES.load(Ordering::Relaxed) - e0;
@@ -156,6 +158,22 @@ fn main() {
in_site as f64 / hz * 1e3,
attributed / hz * 1e3,
);
// RFC 007 deficit hunt: name the losses. Drop/discard columns are
// in would-be delta terms — divide by pct/100 to compare with the
// missing attribution above.
let ms = |c: u64| c as f64 / hz * 1e3;
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 {}",
ms(audit.spin_absorbed_cycles),
ms(audit.park_forgiven_cycles),
ms(audit.drop_park_cycles),
audit.drop_park_n,
ms(audit.drop_yield_cycles),
audit.drop_yield_n,
ms(audit.discard_overmax_cycles),
audit.discard_overmax_n,
audit.discard_unarmed_n
);
smarm::sleep(Duration::from_millis(150));
}
+6
View File
@@ -247,6 +247,12 @@ fn main() {
background.join().unwrap();
print!("{}", smarm::causal::render_summary(&results));
// RFC 007 deficit hunt: SMARM_CAUSAL_AUDIT=1 appends the per-cell
// ledger audit (injected/absorbed/forgiven + drop and discard
// buckets) without touching the pinned summary format.
if std::env::var_os("SMARM_CAUSAL_AUDIT").is_some() {
print!("{}", smarm::causal::render_ledger_audit(&results));
}
let coz = smarm::causal::render_coz(&results);
match std::fs::write("profile.coz", coz) {
Ok(()) => println!("\nwrote profile.coz"),