metrale_speculative/mtp_gate/
driver.rs1use super::*;
11
12impl MtpGate {
13 pub fn observe(&self) -> (crate::snapshot::MtpModeSnap, f32) {
17 use crate::snapshot::MtpModeSnap;
18 let mode = if self.probing {
19 MtpModeSnap::Probing
20 } else {
21 match self.mode {
22 Mode::Mtp => MtpModeSnap::Mtp,
23 Mode::Serial => MtpModeSnap::Serial,
24 }
25 };
26 let stats = match self.mode {
27 Mode::Mtp => &self.mtp,
28 Mode::Serial => &self.serial,
29 };
30 (mode, stats.tps.unwrap_or(0.0) as f32)
31 }
32
33 pub fn new(num_drafts: usize) -> Self {
36 let reprobe = reprobe_tokens();
39 let refresh = serial_refresh_tokens();
40 tracing::info!(
41 "MTP gate: throughput-arbitrated (K={num_drafts}); window={WINDOW_STEPS} steps, \
42 dwell={SWITCH_DWELL_WINDOWS}, reprobe={reprobe} tok, refresh={refresh} tok",
43 );
44 Self {
45 reprobe,
46 refresh,
47 mode: Mode::Mtp,
48 probing: false,
49 probe_windows_left: 0,
50 mtp: ModeStats::default(),
51 serial: ModeStats::default(),
52 win_tokens: 0.0,
53 win_wall: 0.0,
54 win_steps: 0,
55 losing_windows: 0,
56 loss_other_windows: 0,
57 tokens_since_event: 0,
58 observed_depth: 0,
59 measured_at_depth: 0,
60 width_regime: 0,
61 fresh: None,
62 settle_steps: 0,
63 regime_reprobes: 0,
64 }
65 }
66
67 pub fn note_depth(&mut self, depth: usize) {
68 self.observed_depth = depth;
69 }
70
71 pub fn maybe_remeasure(&mut self, current_depth: usize) -> bool {
77 let measured = self.measured_at_depth.max(REMEASURE_DEPTH_FLOOR);
78 let live = current_depth.max(REMEASURE_DEPTH_FLOOR);
79 if live >= measured * REMEASURE_DEPTH_FACTOR || measured >= live * REMEASURE_DEPTH_FACTOR {
80 tracing::info!(
81 "MTP gate: depth regime changed ({} -> {} tokens); baselines stale, \
82 will re-probe on cadence",
83 self.measured_at_depth,
84 current_depth,
85 );
86 self.mtp.stale = true;
87 self.serial.stale = true;
88 self.measured_at_depth = current_depth;
89 self.tokens_since_event = self.tokens_since_event.max(self.event_interval());
91 self.regime_reprobes = self.regime_reprobes.saturating_add(1);
92 true
93 } else {
94 false
95 }
96 }
97
98 pub fn take_fresh_decision(&mut self) -> Option<GateDecision> {
100 self.fresh.take()
101 }
102
103 pub fn next_step(&self) -> GateStep {
105 let effective = if self.probing {
106 Self::other(self.mode)
107 } else {
108 self.mode
109 };
110 match effective {
111 Mode::Mtp => GateStep::MeasureVerify,
112 Mode::Serial => GateStep::MeasureDecode,
113 }
114 }
115
116 pub fn record_decode(&mut self, wall: Duration, width: usize) {
119 self.note_width(width.max(1));
120 self.record_step(wall, width.max(1));
121 }
122
123 pub fn record_verify_step(&mut self, wall: Duration, emitted: usize, width: usize) {
127 self.note_width(width.max(1));
128 self.record_step(wall, emitted.max(1));
129 }
130}