code wiki / (root) / nx_abs_ab.nx

nx_abs_ab.nx source

↩ module page · 94 lines · 3322 B

1// nx_abs_ab.nx -- rigorous SAME-PROCESS A/B of branchy vs branchless abs in 2// the jitter update. Both variants run the IDENTICAL work (only the abs 3// differs), measured INTERLEAVED with min-of-K so between-batch system-load 4// drift and upward noise cancel (RACING_TEAM_BENCHMARK_DOCTRINE: separate 5// signal from confound; min is the least-disturbed estimate). This is the 6// honest way to decide a ~2-cycle question -- single-run amortized numbers 7// across separate processes are dominated by load variance, not the code. 8// 9// license_tier: ORIGINAL 10 11import "nx_syscalls.nx" 12const K_MAGIC_2654435761: i64 = 2654435761 13const K_MAGIC_2000000: i64 = 2000000 14const K_MAGIC_200000: i64 = 200000 15const K_MAGIC_1000000000000: i64 = 1000000000000 16 17func bdec(n: i64) -> i64 { 18 if n == 0 { sys_write(1, "0" as *u8, 1); return 0 } 19 var m: i64 = n 20 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 21 let d: *u8 = sys_mmap(24) 22 var k: i64 = 0 23 while m > 0 { d[k] = (0x30 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 var i: i64 = k - 1 25 while i >= 0 { let one: *u8 = sys_mmap(1); one[0] = d[i]; sys_write(1, one, 1); i = i - 1 } 26 return 0 27} 28 29// branchy: if d<0 { d = -d }. Returns elapsed reference cycles for N iters. 30func run_branchy(n: i64) -> i64 { 31 var jit: i64 = 0 32 var prev: i64 = 0 33 let c0: i64 = __rdtsc() 34 var i: i64 = 0 35 while i < n { 36 let off: i64 = ((i * K_MAGIC_2654435761) >> 13) & 63 37 let transit: i64 = 10 + off 38 var d: i64 = transit - prev 39 prev = transit 40 if d < 0 { d = 0 - d } 41 jit = jit + (d - (jit >> 4)) 42 i = i + 1 43 } 44 let c1: i64 = __rdtsc() 45 if jit < 0 { return 0 - 1 } // anti-fold 46 return c1 - c0 47} 48 49// branchless: s = d>>63; d = (d^s)-s. 50func run_free(n: i64) -> i64 { 51 var jit: i64 = 0 52 var prev: i64 = 0 53 let c0: i64 = __rdtsc() 54 var i: i64 = 0 55 while i < n { 56 let off: i64 = ((i * K_MAGIC_2654435761) >> 13) & 63 57 let transit: i64 = 10 + off 58 var d: i64 = transit - prev 59 prev = transit 60 let s: i64 = d >> 63 61 d = (d ^ s) - s 62 jit = jit + (d - (jit >> 4)) 63 i = i + 1 64 } 65 let c1: i64 = __rdtsc() 66 if jit < 0 { return 0 - 1 } 67 return c1 - c0 68} 69 70func main() -> i64 { 71 let N: i64 = K_MAGIC_2000000 72 let REPS: i64 = 25 73 74 // warmup both (discarded) 75 run_branchy(K_MAGIC_200000); run_free(K_MAGIC_200000) 76 77 var bmin: i64 = K_MAGIC_1000000000000 78 var fmin: i64 = K_MAGIC_1000000000000 79 var k: i64 = 0 80 while k < REPS { 81 let b: i64 = run_branchy(N) // interleaved: same load state 82 if b < bmin { bmin = b } 83 let f: i64 = run_free(N) 84 if f < fmin { fmin = f } 85 k = k + 1 86 } 87 88 sys_write(1, "ABS A/B (same process, interleaved, min of ", 43); bdec(REPS); sys_write(1, " reps, N=", 9); bdec(N); sys_write(1, ")\n", 2) 89 sys_write(1, " branchy (if d<0): ", 21); bdec((bmin * 100) / N); sys_write(1, " cyc/op (x100)\n", 15) 90 sys_write(1, " branchless (d^s)-s: ", 22); bdec((fmin * 100) / N); sys_write(1, " cyc/op (x100)\n", 15) 91 let diff: i64 = ((bmin - fmin) * 100) / N 92 sys_write(1, " delta (branchy - branchless): ", 32); bdec(diff); sys_write(1, " cyc/op (x100); >0 means branchless faster\n", 43) 93 return 0 94}