nx_ppdemo_threads.nx source
↩ module page · 49 lines · 1888 B
1// nx_ppdemo_threads.nx -- REAL multi-core proof via raw __thread_clone (stage-1 func-pointers). Spawns 4 worker
2// threads, each doing a heavy data-dependent LCG loop (not DCE-able); main does the same. 5 compute streams
3// sharing ONE process (CLONE_VM) -> if they run in parallel, nx_parallelism_probe reads cpu/wall ~5 (vs the
4// serial demo's 1.00). This is the codec unlock made measurable. Build with the func-ptr compiler.
5import "nx_syscalls.nx"
6const K_MAGIC_1103515245: i64 = 1103515245
7const K_MAGIC_12345: i64 = 12345
8const K_MAGIC_2147483647: i64 = 2147483647
9const K_MAGIC_262144: i64 = 262144
10const K_MAGIC_5000000000: i64 = 5000000000
11
12const NTHREAD: i64 = 4
13const ITERS: i64 = 1500000000
14
15func hot(ctx: *u8) -> i64 {
16 let slot: *i64 = ctx as *i64 // slot[0]=result, slot[1]=done
17 var s: i64 = 999
18 var i: i64 = 0
19 while i < ITERS { s = (s * K_MAGIC_1103515245 + K_MAGIC_12345) & K_MAGIC_2147483647; i = i + 1 }
20 slot[0] = s
21 slot[1] = 1
22 return 0
23}
24
25func main() -> i64 {
26 let flags: *i64 = sys_mmap(NTHREAD * 16) as *i64
27 var k: i64 = 0
28 while k < NTHREAD {
29 let stack: *u8 = sys_mmap(K_MAGIC_262144)
30 let top: *u8 = ((stack as i64) + K_MAGIC_262144) as *u8
31 let ctx: *u8 = ((flags as i64) + k * 16) as *u8
32 __thread_clone(top, &hot, ctx)
33 k = k + 1
34 }
35 // main also computes (so total cpu = main + NTHREAD workers)
36 var s: i64 = 111
37 var i: i64 = 0
38 while i < ITERS { s = (s * K_MAGIC_1103515245 + K_MAGIC_12345) & K_MAGIC_2147483647; i = i + 1 }
39 // join on each worker's done flag (bounded)
40 var w: i64 = 0
41 while w < NTHREAD {
42 let dptr: *i64 = ((flags as i64) + w * 16) as *i64
43 var spins: i64 = 0
44 while dptr[1] == 0 { spins = spins + 1; if spins > K_MAGIC_5000000000 { dptr[1] = 2 } }
45 w = w + 1
46 }
47 sys_exit(s % 7)
48 return 0
49}