nx_fabric_flow.nx source
↩ module page · 147 lines · 6796 B
1// nx_fabric_flow.nx -- R1 of the SkyHammer scale-up-fabric exceed ladder
2// (knowledge/research/2026-06-23-skyhammer-fabric-sclass-exceed-benchmark.md ยง7).
3//
4// SkyHammer sells "deterministic flow control ... lossless behavior" IN SILICON. At
5// Nishi's altitude (software, commodity HW) the honest, measurable expression is a
6// CREDIT-BASED deterministic flow controller over a bounded-buffer link: the sender
7// may only inject what the receiver has buffer for, so the queue NEVER overflows
8// (lossless) and latency stays BOUNDED (deterministic). An uncontrolled sender, by
9// contrast, overruns the buffer -> drops -> (for reliable delivery) retransmits ->
10// a long latency tail.
11//
12// FOUNDED ON (composes, does not reinvent -- rule #15 / anti-orphan):
13// nx_h2_flow.nx -- the PROVEN credit-window primitive (RFC 9113 6.9: init_to /
14// consume[overdraw->FLOW_CONTROL_ERROR] / apply_window_update). The receiver's
15// free buffer IS the flow-control window; sending CONSUMES it, draining REPLENISHES
16// it (WINDOW_UPDATE). No new flow-control math is authored here -- only the link
17// model + the discrete-event simulation that measures the exceed. Importing
18// nx_h2_flow transitively splices nx_h2_frame->nx_hpack->nx_str->syscalls (single
19// import; importing nx_syscalls too would be the RC6 double-import landmine).
20//
21// Integer-only (no float, ecosystem law). expect_exit: 0 license_tier: ORIGINAL
22import "nx_h2_flow.nx"
23const FF_MAGIC_20000: i64 = 20000
24
25// Simulation modes.
26const FF_UNCTL: i64 = 0 // baseline: sender ignores credit -> overflow drops
27const FF_CREDIT: i64 = 1 // R1: credit-controlled via nx_h2_flow (lossless by construction)
28const FF_NC1: i64 = 2 // NC1: credit BOOKKEEPING runs but the backpressure GATE is removed
29
30struct FfMetrics {
31 drops: i64, // overflow-drops counted AT THE BUFFER (independent of the sender)
32 delivered: i64, // unique frames delivered (== N on success; reliability holds)
33 ticks: i64, // discrete ticks to deliver all N
34 p50: i64, // median delivery latency (first-offer tick -> delivered tick)
35 p99: i64, // p99 delivery latency (the determinism tail)
36 goodput_x1000: i64, // delivered*1000/ticks (scaled int -- no float)
37}
38
39// Deliver N frames RELIABLY over a link with receiver buffer cap B, drain rate D
40// frames/tick, sender offering up to R frames/tick. Fills *m. Returns 0.
41func ff_run_sim(mode: i64, N: i64, B: i64, D: i64, R: i64, m: *FfMetrics) -> i64 {
42 let MAXT: i64 = FF_MAGIC_20000 // safety tick ceiling + histogram size
43 let first_off: *i64 = sys_mmap(N * 8) as *i64 // per-frame first-offer tick (-1 = none)
44 let lat: *i64 = sys_mmap(N * 8) as *i64 // per-frame delivered latency
45 var z: i64 = 0
46 while z < N { first_off[z] = 0 - 1; lat[z] = 0 - 1; z = z + 1 }
47
48 let buf: *i64 = sys_mmap((B + 1) * 8) as *i64 // receiver FIFO ring (B+1 slots)
49 var bhead: i64 = 0
50 var btail: i64 = 0
51 var bocc: i64 = 0
52 let rq: *i64 = sys_mmap(N * 8) as *i64 // retransmit FIFO (reliable delivery)
53 var rhead: i64 = 0
54 var rtail: i64 = 0
55 var rcount: i64 = 0
56 let win: *i64 = sys_mmap(16) as *i64 // the credit window (nx_h2_flow)
57 h2_flow_init_to(win, B) // free buffer == initial credit
58
59 let hist: *i64 = sys_mmap(MAXT * 8) as *i64 // latency histogram (mmap zero-fills)
60 var next_new: i64 = 0
61 var delivered: i64 = 0
62 var drops: i64 = 0
63 var tick: i64 = 0
64
65 while delivered < N {
66 if tick >= MAXT { break } // safety: never spin forever
67
68 // ---- 1. DRAIN up to D frames (receiver consumes the link) ----
69 var dd: i64 = 0
70 while dd < D {
71 if bocc == 0 { break }
72 let fid: i64 = buf[bhead]
73 bhead = bhead + 1; if bhead > B { bhead = 0 }
74 bocc = bocc - 1
75 var L: i64 = tick - first_off[fid]
76 lat[fid] = L
77 if L >= MAXT { L = MAXT - 1 }
78 hist[L] = hist[L] + 1
79 delivered = delivered + 1
80 if mode == FF_CREDIT { h2_flow_apply_window_update(win, 1) } // freed slot -> +1 credit
81 dd = dd + 1
82 }
83
84 // ---- 2. SEND up to R offers (sender injects into the link) ----
85 var ss: i64 = 0
86 while ss < R {
87 // pick a frame: retransmits first (reliability), then a fresh one.
88 var fid: i64 = 0 - 1
89 if rcount > 0 {
90 fid = rq[rhead]; rhead = rhead + 1; if rhead >= N { rhead = 0 }; rcount = rcount - 1
91 } else {
92 if next_new < N { fid = next_new; next_new = next_new + 1 } else { break }
93 }
94 if first_off[fid] < 0 { first_off[fid] = tick }
95
96 // CREDIT mode: consult the window. Exhausted -> BACKPRESSURE: requeue + stop.
97 if mode == FF_CREDIT {
98 if win[0] <= 0 {
99 rq[rtail] = fid; rtail = rtail + 1; if rtail >= N { rtail = 0 }; rcount = rcount + 1
100 break
101 }
102 h2_flow_consume(win, 1)
103 }
104 // NC1: run the SAME bookkeeping but DROP the backpressure gate (never blocks).
105 if mode == FF_NC1 { if win[0] > 0 { h2_flow_consume(win, 1) } }
106
107 // enqueue into the receiver buffer; the BUFFER decides overflow (NC3: the
108 // drop counter lives here, never self-reported by the sender).
109 if bocc < B {
110 buf[btail] = fid; btail = btail + 1; if btail > B { btail = 0 }; bocc = bocc + 1
111 } else {
112 drops = drops + 1
113 rq[rtail] = fid; rtail = rtail + 1; if rtail >= N { rtail = 0 }; rcount = rcount + 1
114 }
115 ss = ss + 1
116 }
117 tick = tick + 1
118 }
119
120 // ---- percentiles from the histogram (over `delivered` frames) ----
121 let t50: i64 = (delivered * 50) / 100
122 let t99: i64 = (delivered * 99) / 100
123 var cum: i64 = 0
124 var p50: i64 = 0
125 var p99: i64 = 0
126 var g50: i64 = 0
127 var g99: i64 = 0
128 var hh: i64 = 0
129 while hh < MAXT {
130 cum = cum + hist[hh]
131 if g50 == 0 { if cum > t50 { p50 = hh; g50 = 1 } }
132 if g99 == 0 { if cum > t99 { p99 = hh; g99 = 1 } }
133 if g99 == 1 { break }
134 hh = hh + 1
135 }
136
137 m.drops = drops
138 m.delivered = delivered
139 m.ticks = tick
140 m.p50 = p50
141 m.p99 = p99
142 if tick > 0 { m.goodput_x1000 = (delivered * 1000) / tick } else { m.goodput_x1000 = 0 }
143 return 0
144}
145
146// compile smoke (the real assertions live in nx_fabric_flow_gate.nx).
147func main() -> i64 { return 0 }