code wiki / (root) / nx_p256_solinas_fast_bench.nx

nx_p256_solinas_fast_bench.nx source

↩ module page · 48 lines · 2600 B

1// nx_p256_solinas_fast_bench.nx -- reduce-only speed: production _p256_solinas_reduce (~60 _r_addw 2// calls, per-add carry propagation) vs the deferred-carry _p256_solinas_reduce_fast. Isolates the 3// reducer (the measured P-256 field-mul bottleneck). Dependent-chain harness (DCE/hoist-proof). 4// No intrinsic -> live toolchain. expect_exit: 0 license_tier: ORIGINAL 5import "nx_p256_solinas_fast.nx" 6const N_MAGIC_1000000000: i64 = 1000000000 7 8const N_ITER: i64 = 3000000 9 10func bp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func bn(v: i64) -> i64 { 12 let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 13 let b: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 14 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var i: i64 = 0; while i < k { b[i] = t[k-1-i]; i = i + 1 } sys_write(1, b, k); return 0 16} 17func now_ns(ts: *i64) -> i64 { __syscall(SYS_CLOCK_GETTIME, 1, ts as i64, 0, 0, 0, 0); return ts[0] * N_MAGIC_1000000000 + ts[1] } 18 19func main() -> i64 { 20 let c: *i64 = sys_mmap(16 * 8) as *i64 21 let r: *i64 = sys_mmap(8 * 8) as *i64 22 let ts: *i64 = sys_mmap(32) as *i64 23 var k: i64 = 0 24 while k < 16 { c[k] = (0x9e3779b97f4a7c15 * (k + 1)) & 0xffffffff; k = k + 1 } 25 let c0_init: i64 = c[0] // same starting point for BOTH chains -> checksums must match (in-bench correctness) 26 27 bp("=== nx_p256_solinas_fast_bench: production reduce vs deferred-carry fast reduce ===\n" as *u8) 28 29 var accp: i64 = 0 30 let t0: i64 = now_ns(ts) 31 k = 0 32 while k < N_ITER { c[0] = (c[0] ^ accp) & 0xffffffff; p256_field_reduce_solinas(r, c); accp = accp ^ r[0] ^ r[3] ^ r[7]; k = k + 1 } 33 let prod_ns: i64 = now_ns(ts) - t0 34 35 c[0] = c0_init 36 var accf: i64 = 0 37 let t2: i64 = now_ns(ts) 38 k = 0 39 while k < N_ITER { c[0] = (c[0] ^ accf) & 0xffffffff; p256_field_reduce_solinas_fast(r, c); accf = accf ^ r[0] ^ r[3] ^ r[7]; k = k + 1 } 40 let fast_ns: i64 = now_ns(ts) - t2 41 42 bn(N_ITER); bp(" iters\n" as *u8) 43 bp("production_reduce = " as *u8); bn(prod_ns); bp(" (" as *u8); bn(prod_ns / N_ITER); bp(" ns/op)\n" as *u8) 44 bp("fast_reduce = " as *u8); bn(fast_ns); bp(" (" as *u8); bn(fast_ns / N_ITER); bp(" ns/op)\n" as *u8) 45 if fast_ns > 0 { bp("speedup_x100 = " as *u8); bn(prod_ns * 100 / fast_ns); bp(" (100 = parity, >100 = fast faster)\n" as *u8) } 46 bp("checksums accp=" as *u8); bn(accp); bp(" accf=" as *u8); bn(accf); bp(" (EQUAL = same computation)\n" as *u8) 47 return 0 48}