code wiki / _hdl_build / nx_fkbench.nx
nx_fkbench.nx source
↩ module page · 91 lines · 3317 B
1// nx_fkbench.nx -- fannkuch-redux(N) sovereign runtime bench (fixed clock: sys_now_us).
2// Identical hot loop to nx_clbg_fannkuch.nx; times FK_REPEAT enumerations to compare
3// nx_cc codegen RUNTIME vs gcc -O2/-O3 on the SAME algorithm (per-rung compiler grade).
4import "nx_syscalls.nx"
5import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
6
7const FK_MAXN: i64 = 32
8const FK_INTSZ: i64 = 8
9const FK_DEFAULT_N: i64 = 11 // 11! = 39.9M perms; checksum 556355 maxflips 51
10const FK_REPEAT: i64 = 5
11
12func fannkuch_redux(n: i64, out: *i64) -> i64 {
13 if n < 1 { return 0 - 1 }
14 if n > FK_MAXN { return 0 - 1 }
15 let perm: *i64 = sys_mmap(FK_MAXN * FK_INTSZ) as *i64
16 let perm1: *i64 = sys_mmap(FK_MAXN * FK_INTSZ) as *i64
17 let count: *i64 = sys_mmap(FK_MAXN * FK_INTSZ) as *i64
18 var i: i64 = 0
19 while i < n { perm1[i] = i; i = i + 1 }
20 var checksum: i64 = 0
21 var maxflips: i64 = 0
22 var sign: i64 = 1
23 var r: i64 = n
24 var done: i64 = 0
25 while done == 0 {
26 while r != 1 { count[r - 1] = r; r = r - 1 }
27 var c: i64 = 0
28 while c < n { perm[c] = perm1[c]; c = c + 1 }
29 var flips: i64 = 0
30 var k: i64 = perm[0]
31 while k != 0 {
32 var lo: i64 = 0
33 var hi: i64 = k
34 while lo < hi {
35 let t: i64 = perm[lo]
36 perm[lo] = perm[hi]
37 perm[hi] = t
38 lo = lo + 1
39 hi = hi - 1
40 }
41 flips = flips + 1
42 k = perm[0]
43 }
44 if flips > maxflips { maxflips = flips }
45 if sign > 0 { checksum = checksum + flips }
46 if sign < 0 { checksum = checksum - flips }
47 sign = 0 - sign
48 var adv: i64 = 0
49 while adv == 0 {
50 if r == n { out[0] = checksum; out[1] = maxflips; return 0 }
51 let perm0: i64 = perm1[0]
52 var m: i64 = 0
53 while m < r { perm1[m] = perm1[m + 1]; m = m + 1 }
54 perm1[r] = perm0
55 count[r] = count[r] - 1
56 if count[r] > 0 { adv = 1 }
57 if adv == 0 { r = r + 1 }
58 }
59 }
60 out[0] = checksum
61 out[1] = maxflips
62 return 0
63}
64
65func fk_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
66// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
67// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
68// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
69// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
70func fk_putn(v: i64) -> i64 { nxi_out(v); return 0 }
71
72func main() -> i64 {
73 let out: *i64 = sys_mmap(2 * FK_INTSZ) as *i64
74 out[0] = 0
75 out[1] = 0
76 let t0: i64 = sys_now_us()
77 var rep: i64 = 0
78 while rep < FK_REPEAT {
79 fannkuch_redux(FK_DEFAULT_N, out)
80 rep = rep + 1
81 }
82 let t1: i64 = sys_now_us()
83 let sov_us: i64 = (t1 - t0) / FK_REPEAT
84 fk_puts("FANNKUCH_SOV n=" as *u8); fk_putn(FK_DEFAULT_N)
85 fk_puts(" checksum=" as *u8); fk_putn(out[0])
86 fk_puts(" maxflips=" as *u8); fk_putn(out[1])
87 fk_puts(" sov_us=" as *u8); fk_putn(sov_us)
88 fk_puts(" reps=" as *u8); fk_putn(FK_REPEAT)
89 fk_puts("\n" as *u8)
90 return 0
91}