_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}