code wiki / _hdl_build / nx_bench_vs_c.nx

nx_bench_vs_c.nx source

↩ module page · 78 lines · 4310 B

1// nx_bench_vs_c.nx -- HORIZONTAL benchmark organ (Referee/Engineer-owned): races the sovereign 2// toolchain against the C toolchain (gcc) on the SAME .s artifact -- the operator-sanctioned use 3// of C ("benchmarking only"). For argv[1]=<name> (expects /tmp/<name>.s from nx_sov_build_run): 4// lane A: nxasm_x86_main .s -> ELF (ours) timed ms 5// lane B: gcc -nostdlib .s -> ELF (C oracle) timed ms 6// then RUNS both ELFs and compares exit codes (differential correctness, csmith-lite). 7// Emits one parseable line appended to /tmp/nishi_ladder.log for the wiki ladder: 8// BENCH name= sov_ms= gcc_ms= sov_exit= gcc_exit= agree= 9// license_tier: ORIGINAL (fork/exec spine reused from nx_sov_build_run) 10import "nx_syscalls.nx" 11import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 12 13func bv_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 14// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 15// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 16// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 17// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 18func bv_n(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 19func bv_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i } 20 21func bv_run(path: *u8, argv: *i64, envp: *i64) -> i64 { 22 let pid: i64 = sys_fork() 23 if pid == 0 { sys_execve(path, argv, envp); sys_exit(127) } 24 let st: *i64 = sys_mmap(16) as *i64 25 sys_wait4(pid, st, 0) 26 let sig: i64 = st[0] & 0x7f 27 if sig != 0 { return 128 + sig } 28 return (st[0] >> 8) & 0xff 29} 30 31func main(argc: i64, argv: *i64) -> i64 { 32 if argc < 2 { bv_w(1, "usage: nx_bench_vs_c <name> (needs /tmp/<name>.s)\n" as *u8); sys_exit(2); return 2 } 33 let name: *u8 = argv[1] as *u8 34 let envp: *i64 = sys_mmap(32) as *i64 35 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 36 let sp: *u8 = sys_mmap(256); var o: i64 = bv_cat(sp,0,"/tmp/" as *u8); o=bv_cat(sp,o,name); o=bv_cat(sp,o,".s" as *u8); sp[o]=0 as u8 37 let ea: *u8 = sys_mmap(256); o = bv_cat(ea,0,"/tmp/" as *u8); o=bv_cat(ea,o,name); o=bv_cat(ea,o,".bvA.elf" as *u8); ea[o]=0 as u8 38 let eb: *u8 = sys_mmap(256); o = bv_cat(eb,0,"/tmp/" as *u8); o=bv_cat(eb,o,name); o=bv_cat(eb,o,".bvB.elf" as *u8); eb[o]=0 as u8 39 40 // lane A: sovereign assembler 41 let t0: i64 = sys_now_ms() 42 let aa: *i64 = sys_mmap(40) as *i64 43 aa[0] = "_offc/nxasm_x86_main.elf" as *u8 as i64; aa[1] = sp as i64; aa[2] = ea as i64; aa[3] = 0 44 let rca: i64 = bv_run("_offc/nxasm_x86_main.elf" as *u8, aa, envp) 45 let sov_ms: i64 = sys_now_ms() - t0 46 // lane B: the C toolchain (gcc as assembler+linker), the sanctioned oracle 47 let t1: i64 = sys_now_ms() 48 let bb: *i64 = sys_mmap(80) as *i64 49 bb[0] = "/usr/bin/gcc" as *u8 as i64; bb[1] = "-nostdlib" as *u8 as i64; bb[2] = "-no-pie" as *u8 as i64 50 bb[3] = "-static" as *u8 as i64; bb[4] = sp as i64; bb[5] = "-o" as *u8 as i64; bb[6] = eb as i64; bb[7] = 0 51 let rcb: i64 = bv_run("/usr/bin/gcc" as *u8, bb, envp) 52 let gcc_ms: i64 = sys_now_ms() - t1 53 54 // differential run (only if both built) 55 var e1: i64 = 0 - 1 56 var e2: i64 = 0 - 2 57 if rca == 0 { let ra: *i64 = sys_mmap(16) as *i64; ra[0]=ea as i64; ra[1]=0; e1 = bv_run(ea, ra, envp) } 58 if rcb == 0 { let rb: *i64 = sys_mmap(16) as *i64; rb[0]=eb as i64; rb[1]=0; e2 = bv_run(eb, rb, envp) } 59 var agree: i64 = 0 60 if e1 == e2 { agree = 1 } 61 62 let lfd: i64 = sys_openat_append("/tmp/nishi_ladder.log" as *u8, 0x1a4) 63 var f: i64 = 1 64 while f >= 0 { 65 let fd: i64 = lfd * f + 1 * (1 - f) // f=1 -> ladder log, f=0 -> stdout 66 bv_w(fd, "BENCH name=" as *u8); bv_w(fd, name) 67 bv_w(fd, " sov_ms=" as *u8); bv_n(fd, sov_ms) 68 bv_w(fd, " gcc_ms=" as *u8); bv_n(fd, gcc_ms) 69 bv_w(fd, " sov_exit=" as *u8); bv_n(fd, e1) 70 bv_w(fd, " gcc_exit=" as *u8); bv_n(fd, e2) 71 bv_w(fd, " agree=" as *u8); bv_n(fd, agree) 72 bv_w(fd, "\n" as *u8) 73 f = f - 1 74 } 75 sys_close(lfd) 76 if agree == 0 { sys_exit(1); return 1 } 77 sys_exit(0); return 0 78}