nx_lcg_bench.nx source
↩ module page · 47 lines · 1872 B
1// nx_lcg_bench.nx -- HONEST cross-language grounding bench (NishiLang side). SAME workload as
2// bench_lcg.c: LCG x=x*A+C accumulated over N=1e8 iterations (64-bit wrapping, serial recurrence ->
3// unfoldable/unvectorizable). Prints "acc elapsed_us". acc MUST equal the C/clang/python acc
4// (2849182864005356672) = correctness; elapsed_us vs gcc's 83ms = the real codegen gap.
5// NOT smelling our own farts: this is nx_cc's tight-loop x86_64 codegen measured against gcc -O2.
6// license_tier: ORIGINAL No hw writes (Rule 26).
7// (nx_syscalls_x86_64.nx import REMOVED 2026-07-31, debt 1785528831: this file already
8// gets the canonical syscall layer via nx_clock.nx -> syscalls.nx, so importing the raw-x86
9// module too put TWO syscall layers in one TU -- every wrapper twice, numbering picked by
10// definition ORDER, silently.)
11import "nx_clock.nx"
12
13func lcg_emit_i64(fd: i64, n: i64) -> i64 {
14 let scratch: *u8 = sys_mmap(32)
15 var v: i64 = n
16 var neg: nx_int = 0
17 if v < 0 { neg = 1; v = 0 - v }
18 var k: i64 = 0
19 if v == 0 { scratch[0] = 0x30 as u8; k = 1 }
20 while v > 0 { scratch[k] = (0x30 + (v - (v / 10) * 10)) as u8; v = v / 10; k = k + 1 }
21 let rev: *u8 = sys_mmap(48)
22 var ro: i64 = 0
23 if neg == 1 { rev[0] = 0x2D as u8; ro = 1 }
24 var j: i64 = 0
25 while j < k { rev[ro + j] = scratch[k - 1 - j]; j = j + 1 }
26 rev[ro + k] = 0x0A as u8
27 sys_write(fd, rev, ro + k + 1)
28 return 0
29}
30
31func main() -> i64 {
32 let N: i64 = 100000000
33 var x: i64 = 1
34 var acc: i64 = 0
35 let start: i64 = nx_clock_monotonic_ns()
36 var i: i64 = 0
37 while i < N {
38 x = x * 6364136223846793005 + 1442695040888963407
39 acc = acc + x
40 i = i + 1
41 }
42 let end: i64 = nx_clock_monotonic_ns()
43 let elapsed_us: i64 = (end - start) / 1000
44 lcg_emit_i64(1, acc)
45 lcg_emit_i64(1, elapsed_us)
46 return 0
47}