code wiki / (root) / _nx_bits_speed_paired.nx

_nx_bits_speed_paired.nx source

↩ module page · 87 lines · 2374 B

1// _nx_bits_speed_paired.nx 2// 3// Paired speed bench: 10M-iteration popcount on the same data via 4// FAST (intrinsic dispatch) vs SOFT (SWAR) paths. Substrate writes 5// nanoseconds for each path to stdout via sys_write. Harness picks 6// the timing apart and emits a sealed BEATS/EQUIVALENT verdict. 7// 8// Honest-measurement discipline: same compiled-in input mix, same 9// loop structure, only difference is the function called. 10 11import "syscalls.nx" 12import "nx_bits.nx" 13import "nx_clock.nx" 14 15// Tiny helper: print an i64 as decimal followed by a newline. 16func _print_dec(n: i64) -> i64 { 17 let buf: *u8 = sys_mmap(32) 18 var v: i64 = n 19 if v < 0 { v = 0 - v } 20 var p: i64 = 30 21 if v == 0 { 22 buf[p] = 48 as u8 23 p = p - 1 24 } else { 25 while v > 0 { 26 let d: i64 = v - ((v / 10) * 10) 27 buf[p] = (48 + d) as u8 28 p = p - 1 29 v = v / 10 30 } 31 } 32 if n < 0 { 33 buf[p] = 45 as u8 34 p = p - 1 35 } 36 let start: i64 = p + 1 37 let len: i64 = 31 - start 38 buf[31] = 10 as u8 // newline 39 let bp: *u8 = buf + start 40 let _w: i64 = sys_write(1, bp, len + 1) 41 return 0 42} 43 44func main() -> i64 { 45 let iters: i64 = 10000000 46 let seed: i64 = 0xCAFEBABE12345678 47 var acc: i64 = 0 48 var x: i64 = seed 49 var i: i64 = 0 50 51 // ===== FAST path ===== 52 let t_fast_a: i64 = nx_clock_monotonic_ns() 53 i = 0 54 x = seed 55 acc = 0 56 while i < iters { 57 acc = acc + nx_bits_popcount64(x) 58 // Mix x so dead-code elimination can't fold it. 59 x = x * 6364136223846793005 + 1442695040888963407 60 i = i + 1 61 } 62 let t_fast_b: i64 = nx_clock_monotonic_ns() 63 let fast_ns: i64 = t_fast_b - t_fast_a 64 let fast_acc: i64 = acc 65 66 // ===== SOFT path ===== 67 let t_soft_a: i64 = nx_clock_monotonic_ns() 68 i = 0 69 x = seed 70 acc = 0 71 while i < iters { 72 acc = acc + nx_bits_popcount64_soft(x) 73 x = x * 6364136223846793005 + 1442695040888963407 74 i = i + 1 75 } 76 let t_soft_b: i64 = nx_clock_monotonic_ns() 77 let soft_ns: i64 = t_soft_b - t_soft_a 78 let soft_acc: i64 = acc 79 80 // Acc must match (correctness guard). 81 if fast_acc != soft_acc { return 1 } 82 83 // Print fast_ns then soft_ns; harness reads them. 84 let _a: i64 = _print_dec(fast_ns) 85 let _b: i64 = _print_dec(soft_ns) 86 return 0 87}