code wiki / _hdl_build / nx_adverse_net_gate.nx
nx_adverse_net_gate.nx source
↩ module page · 172 lines · 9069 B
1// nx_adverse_net_gate.nx -- THE MEASURED ADVERSE-NETWORK SCORECARD (NET-R6, no-wave).
2// Simulates "a girl on a bad mobile link (high latency + jitter + ~8% loss + reorder) playing with a
3// boy in Texas" and runs the FULL sovereign netcode stack over the trace vs a NAIVE baseline:
4// bandwidth : nx_netquant delta bit-coding vs raw 28-byte frames
5// smoothness : nx_interp + dead-reckoning vs snap-to-latest (zero-order hold)
6// reliability: nx_fec_xor zero-RTT recovery vs best-effort (no recovery)
7// latency : nx_jitterbuf adaptive playout delay -- reported as the HONEST cost (not a "win")
8// WIN is asserted ONLY where measured; the playout-delay latency is reported, not hidden.
9// Built nx_cc_sovereign -> nxasm_x86 (no gcc, no .sh). license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_gate_emit_lib.nx"
12import "nx_netquant.nx"
13import "nx_interp.nx"
14import "nx_jitterbuf.nx"
15import "nx_fec_xor.nx"
16
17func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
18// ground-truth path: walk out, turn at t=1500, walk back (a direction change -> honest interp/extrap error)
19func pos(t: i64) -> i64 { if t <= 1500 { return t / 3 } return 500 - (t - 1500) / 3 }
20// deterministic adverse link: jitter in [-80,80], ~8% loss (never the first packet)
21func jit(i: i64) -> i64 { return ((i * 37) % 161) - 80 }
22func lost(i: i64) -> i64 { if i == 0 { return 0 } if (i * 13) % 12 == 0 { return 1 } return 0 }
23func setx(f: *i64, x: i64) -> i64 { var j: i64=0; while j<10 { f[j]=0; j=j+1 } f[0]=x; return 0 }
24func fcopy(d: *i64, s: *i64) -> i64 { var j: i64=0; while j<10 { d[j]=s[j]; j=j+1 } return 0 }
25
26func main() -> i64 {
27 g_puts("nx_adverse_net SCORECARD (NET-R6): bad-mobile x Texas, full stack vs naive (no-wave)\n" as *u8)
28 var pass: i64 = 0; var total: i64 = 0
29
30 let NS: i64 = 45 // snapshots
31 let TICK: i64 = 67 // ~15 Hz send
32 let DISP: i64 = 33 // ~30 Hz display
33 let SESS: i64 = 3000
34 let LAT: i64 = 150 // base one-way latency (cross-country + mobile)
35 let KINT: i64 = 10 // keyframe interval (resync)
36 let MAXEX: i64 = 300
37
38 let buf: *u8 = sys_mmap(64)
39 let fcur: *i64 = sys_mmap(10*8) as *i64
40 let fprev: *i64 = sys_mmap(10*8) as *i64
41 let ff: *i64 = sys_mmap(10*8) as *i64
42 let out: *i64 = sys_mmap(10*8) as *i64
43 let rst: *i64 = sys_mmap(64*8) as *i64 // received: server time
44 let rarr:*i64 = sys_mmap(64*8) as *i64 // arrival time
45 let rval:*i64 = sys_mmap(64*8) as *i64 // x value
46 var nr: i64 = 0
47 var nishi_bytes: i64 = 0
48 var naive_bytes: i64 = 0
49
50 // ---- send loop: measure bandwidth + build the received (lossy) stream ----
51 var i: i64 = 0
52 while i < NS {
53 let st: i64 = i * TICK
54 let x: i64 = pos(st)
55 setx(fcur, x)
56 if (i % KINT) == 0 { nishi_bytes = nishi_bytes + nx_bits_bytes(nq_pack_full(buf, fcur)) }
57 else { nishi_bytes = nishi_bytes + nx_bits_bytes(nq_pack_delta(buf, fprev, fcur)) }
58 naive_bytes = naive_bytes + 28
59 fcopy(fprev, fcur)
60 if lost(i) == 0 {
61 rst[nr] = st; rarr[nr] = st + LAT + jit(i); rval[nr] = x; nr = nr + 1
62 }
63 i = i + 1
64 }
65 // sort received by arrival (insertion sort, 3 parallel arrays) -- models reorder at the receiver
66 var a: i64 = 1
67 while a < nr {
68 let ka: i64 = rarr[a]; let ks: i64 = rst[a]; let kv: i64 = rval[a]
69 var b: i64 = a - 1
70 var go: i64 = 1
71 while go == 1 {
72 if b < 0 { go = 0 } else {
73 if rarr[b] > ka { rarr[b+1]=rarr[b]; rst[b+1]=rst[b]; rval[b+1]=rval[b]; b = b - 1 } else { go = 0 }
74 }
75 }
76 rarr[b+1]=ka; rst[b+1]=ks; rval[b+1]=kv
77 a = a + 1
78 }
79
80 // ---- jitterbuf -> adaptive playout delay (the honest latency cost) ----
81 let jb: *i64 = sys_mmap(8*8) as *i64
82 jb_init(jb, TICK, 100, 600)
83 var k: i64 = 0
84 while k < nr { jb_on_recv(jb, rarr[k]); k = k + 1 }
85 let PD: i64 = jb_playout(jb)
86
87 // ---- render loop: smoothness (frame-to-frame jump) + Nishi fidelity-to-target ----
88 let HK: i64 = 48
89 let hist: *i64 = sys_mmap((1 + HK*IP_STRIDE) * 8) as *i64
90 ip_init(hist)
91 var pidx: i64 = 0
92 var prev_rx: i64 = 0 - 999999
93 var prev_nv: i64 = 0 - 999999
94 var jump_nishi: i64 = 0
95 var jump_naive: i64 = 0
96 var fid_max: i64 = 0
97 var fid_sum: i64 = 0
98 var fid_cnt: i64 = 0
99 var dt: i64 = 0
100 while dt <= SESS {
101 var go2: i64 = 1
102 while go2 == 1 {
103 if pidx < nr { if rarr[pidx] <= dt { setx(ff, rval[pidx]); ip_push(hist, HK, rst[pidx], ff); pidx = pidx + 1 } else { go2 = 0 } } else { go2 = 0 }
104 }
105 let rtm: i64 = dt - PD
106 if rtm >= 0 {
107 let stt: i64 = ip_sample_ex(hist, rtm, MAXEX, out)
108 if stt > 0 {
109 let rx: i64 = out[0]
110 if prev_rx > 0 - 999999 { let j: i64 = g_abs(rx - prev_rx); if j > jump_nishi { jump_nishi = j } }
111 prev_rx = rx
112 let fe: i64 = g_abs(rx - pos(rtm)); if fe > fid_max { fid_max = fe }
113 fid_sum = fid_sum + fe; fid_cnt = fid_cnt + 1
114 }
115 }
116 if pidx > 0 {
117 let nv: i64 = rval[pidx - 1] // naive shows the newest-ARRIVED state (reorder -> jumps)
118 if prev_nv > 0 - 999999 { let j: i64 = g_abs(nv - prev_nv); if j > jump_naive { jump_naive = j } }
119 prev_nv = nv
120 }
121 dt = dt + DISP
122 }
123
124 // ---- FEC reliability: post-recovery effective loss vs raw loss (zero-RTT, no retransmit) ----
125 let L: i64 = 4; let D: i64 = 3; let S: i64 = 12; let BK: i64 = L*D
126 let src: *u8 = sys_mmap(BK*S); let rows: *u8 = sys_mmap(D*S); let cols: *u8 = sys_mmap(L*S)
127 let present: *i64 = sys_mmap(BK*8) as *i64
128 let rpz: *i64 = sys_mmap(D*8) as *i64
129 let cpz: *i64 = sys_mmap(L*8) as *i64
130 var raw_lost: i64 = 0
131 var eff_lost: i64 = 0
132 var blk: i64 = 0
133 while blk * BK < NS {
134 var z: i64 = 0
135 while z < BK { let p: *u8 = fec_pkt(src, z, S); var bb: i64=0; while bb<S { p[bb]=((z*5+bb)&0xff) as u8; bb=bb+1 } z=z+1 }
136 fec_encode_rows(src, L, D, S, rows); fec_encode_cols(src, L, D, S, cols)
137 var z2: i64 = 0; while z2 < BK { present[z2]=1; z2=z2+1 }
138 var z3: i64 = 0; while z3 < D { rpz[z3]=1; z3=z3+1 }
139 var z4: i64 = 0; while z4 < L { cpz[z4]=1; z4=z4+1 }
140 z = 0
141 while z < BK {
142 let gi: i64 = blk*BK + z
143 if gi < NS { if lost(gi) == 1 { present[z]=0; fec_zero(fec_pkt(src,z,S), S); raw_lost = raw_lost + 1 } }
144 z = z + 1
145 }
146 let rem: i64 = fec_decode_2d(src, L, D, S, present, rows, rpz, cols, cpz)
147 eff_lost = eff_lost + rem
148 blk = blk + 1
149 }
150
151 // ================= SCORECARD =================
152 g_puts(" -------------------------------------------------------------\n" as *u8)
153 g_puts(" BANDWIDTH nishi=" as *u8); g_pn(nishi_bytes); g_puts(" B naive=" as *u8); g_pn(naive_bytes); g_puts(" B (over " as *u8); g_pn(NS); g_puts(" snapshots)\n" as *u8)
154 g_puts(" SMOOTHNESS max frame jump: nishi=" as *u8); g_pn(jump_nishi); g_puts(" naive=" as *u8); g_pn(jump_naive); g_puts(" (lower=smoother)\n" as *u8)
155 g_puts(" RELIABILITY raw_lost=" as *u8); g_pn(raw_lost); g_puts(" -> post-FEC eff_lost=" as *u8); g_pn(eff_lost); g_puts(" (zero retransmit)\n" as *u8)
156 var fid_avg: i64 = 0
157 if fid_cnt > 0 { fid_avg = fid_sum / fid_cnt }
158 g_puts(" FIDELITY nishi reconstruction err vs target: avg=" as *u8); g_pn(fid_avg); g_puts(" max=" as *u8); g_pn(fid_max); g_puts(" voxels (max spike is the hard direction-reversal frame)\n" as *u8)
159 g_puts(" LATENCY nishi adaptive playout delay = " as *u8); g_pn(PD); g_puts(" ms (HONEST cost: trades lag for smoothness)\n" as *u8)
160 g_puts(" -------------------------------------------------------------\n" as *u8)
161
162 pass = pass + g_check("BANDWIDTH: nishi delta-coding << naive raw frames" as *u8, nishi_bytes < naive_bytes); total=total+1
163 pass = pass + g_check("SMOOTHNESS: nishi max frame-jump < naive (seamless)" as *u8, jump_nishi < jump_naive); total=total+1
164 pass = pass + g_check("RELIABILITY: post-FEC effective loss < raw loss (zero-RTT recovery)" as *u8, eff_lost < raw_lost); total=total+1
165 // honest bound: avg near-zero on steady motion; max < 2 snapshot-intervals of motion (~44) AND < 8% of the 500-voxel path
166 pass = pass + g_check("FIDELITY: avg err small (<=15) AND max bounded (<2 snapshot-intervals, <=44)" as *u8, (fid_avg <= 15) & (fid_max <= 44)); total=total+1
167 pass = pass + g_check("LATENCY reported honestly (playout delay > 0, a real cost)" as *u8, PD > 0); total=total+1
168
169 g_puts("---- adverse-net scorecard: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
170 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
171 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
172}