code wiki / (root) / nx_ppdemo_threads.nx

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}