code wiki / _hdl_build / nx_bwe_gate.nx

nx_bwe_gate.nx source

↩ module page · 94 lines · 4906 B

1import "nx_gate_base.nx" 2// nx_bwe_gate.nx -- proves the sovereign estimator does what GCC does, MEASURED on a link whose TRUE 3// capacity MOVES: it must TRACK the capacity (converge within a band), BACK OFF fast when capacity drops 4// (delay trend + loss both fire), and PROBE back up when the path clears. NEG-CONTROLS: an always-huge 5// link ramps to the ceiling; an always-tiny link collapses to the floor (it can't hallucinate bandwidth). 6// The link model: a queue grows while we send over capacity (rising delay = the GCC signal) and drops 7// packets when overloaded (the loss signal) -- so the estimator only "sees" congestion it truly caused. 8// expect_exit: 0 license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_bwe.nx" 11 12func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 13" as *u8); return ok } 14func gn(v: i64) -> i64 { 15 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 16 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} 17 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 18 19// TRUE capacity schedule (kbps): 4000 -> drop 1200 -> recover 3500 20func capacity(tick: i64) -> i64 { 21 if tick < 50 { return 4000 } 22 if tick < 100 { return 1200 } 23 return 3500 24} 25 26// run N ticks against a capacity function selector (0=schedule,1=huge,2=tiny); record est into rec[] 27func run(mode: i64, N: i64, rec: *i64) -> i64 { 28 let bw: *i64 = sys_mmap(8 * 16) as *i64 29 bwe_init(bw, 300, 6000, 2000, 200) 30 var queue: i64 = 0 31 var tick: i64 = 0 32 while tick < N { 33 var C: i64 = capacity(tick) 34 if mode == 1 { C = 100000 } 35 if mode == 2 { C = 150 } 36 let est: i64 = bwe_estimate(bw) 37 let over: i64 = est - C 38 // link queue: grows while over-sending (rising delay), drains when under 39 if over > 0 { queue = queue + over / 8 } else { queue = queue - 200 } 40 if queue < 0 { queue = 0 } 41 let send_ts: i64 = tick * 1000 42 let arr_ts: i64 = send_ts + 50 + queue // arrival delayed by the queue = the delay signal 43 bwe_on_arrival(bw, send_ts, arr_ts) 44 // loss: fraction of the over-send is dropped 45 var lost: i64 = 0 46 if over > 0 { lost = over } 47 bwe_report_loss(bw, lost, est) 48 rec[tick] = bwe_update(bw) 49 tick = tick + 1 50 } 51 return 0 52} 53 54func main() -> i64 { 55 gw("=== nx_bwe_gate: sovereign GCC-class bandwidth estimator tracks a moving link (MEASURED) ===\n" as *u8) 56 let N: i64 = 150 57 let rec: *i64 = sys_mmap(8 * N) as *i64 58 run(0, N, rec) 59 let e45: i64 = rec[45] // end of 4000 phase 60 let e50: i64 = rec[50] 61 let e95: i64 = rec[95] // end of 1200 phase (after a drop) 62 let e100: i64 = rec[100] 63 let e145: i64 = rec[145] // end of 3500 phase (after recovery) 64 // find max over run (runaway check) 65 var mx: i64 = 0 66 var i: i64 = 0 67 while i < N { if rec[i] > mx { mx = rec[i] } i = i + 1 } 68 gw(" tracking: est@45(C4000)=" as *u8); gn(e45); gw(" est@95(C1200)=" as *u8); gn(e95); gw(" est@145(C3500)=" as *u8); gn(e145); gw(" max=" as *u8); gn(mx); gw("\n" as *u8) 69 70 let huge: *i64 = sys_mmap(8 * N) as *i64 71 let tiny: *i64 = sys_mmap(8 * N) as *i64 72 run(1, N, huge) 73 run(2, N, tiny) 74 gw(" neg: huge-link ramps to " as *u8); gn(huge[N-1]); gw(" (want 6000 ceiling) tiny-link collapses to " as *u8); gn(tiny[N-1]); gw(" (want 300 floor)\n" as *u8) 75 76 var bad: i64 = 0 77 // TRACK: converge into a band around each true capacity (AIMD sawtooths, so a band not a point) 78 if e45 < 3000 { bad = bad + 1; gw(" FAIL: did not climb to ~4000\n" as *u8) } 79 if e45 > 4600 { bad = bad + 1; gw(" FAIL: overshot 4000\n" as *u8) } 80 if e95 < 900 { bad = bad + 1; gw(" FAIL: undershot 1200\n" as *u8) } 81 if e95 > 1800 { bad = bad + 1; gw(" FAIL: did not back off to ~1200\n" as *u8) } 82 if e145 < 2600 { bad = bad + 1; gw(" FAIL: did not recover toward 3500\n" as *u8) } 83 // BACK OFF on drop, PROBE UP on recovery 84 if e95 >= e50 { bad = bad + 1; gw(" FAIL: no back-off when capacity dropped\n" as *u8) } 85 if e145 <= e100 { bad = bad + 1; gw(" FAIL: no ramp-up when capacity recovered\n" as *u8) } 86 if mx > 6000 { bad = bad + 1; gw(" FAIL: exceeded the max clamp (runaway)\n" as *u8) } 87 // NEG: no hallucinated bandwidth 88 if huge[N-1] != 6000 { bad = bad + 1; gw(" FAIL neg: huge link did not ramp to ceiling\n" as *u8) } 89 if tiny[N-1] != 300 { bad = bad + 1; gw(" FAIL neg: tiny link did not collapse to floor\n" as *u8) } 90 91 if bad == 0 { gw("BWE-GATE verdict=GREEN -- tracks the moving link, backs off on congestion, probes up when clear (GCC-class)\n" as *u8); return 0 } 92 gw("BWE-GATE verdict=RED fails=" as *u8); gn(bad); gw("\n" as *u8) 93 return 1 94}