code wiki / _hdl_build / nx_f32_matmul_perf.nx
nx_f32_matmul_perf.nx source
↩ module page · 64 lines · 3053 B
1// nx_f32_matmul_perf.nx -- MEASURE the sovereign f32 GEMM's throughput (the math-perf rung).
2//
3// Times nx_f32_matmul SOVEREIGNLY -- the clock (sys_now_ms) is read INSIDE the organ around the
4// work (per "monitor the system natively, never a host stopwatch"). Reports measured MFLOP/s + ns
5// per MAC across a few sizes, with adaptive repetition so the timed window is meaningful.
6//
7// HONEST (no wave, no fabricated head-to-head): this is OUR sovereign BITS-UP f32 GEMM -- no hardware
8// FPU, no SIMD, no BLAS. BLAS/cuBLAS are NOT run here (they are 3rd-party, bench-lane only); the
9// literature ceiling is ~tens of GFLOP/s single-thread, so the measured number below is the sovereign
10// BASELINE and the gap to that ceiling is exactly the simd/FPU lock the genealogy names.
11// Sovereign: imports nx_f32_matmul (-> nx_f32) + nx_syscalls. license_tier: ORIGINAL
12import "nx_f32_matmul.nx"
13import "nx_syscalls.nx"
14const K_MAGIC_8192: i64 = 8192
15const K_MAGIC_1000000: i64 = 1000000
16
17func p_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
18func p_putn(v: i64) -> i64 {
19 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
20 var m: i64 = v
21 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
22 let d: *u8 = sys_mmap(24); var k: i64 = 0
23 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
24 var j: i64 = k - 1
25 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
26 return 0
27}
28
29// measure NxN @ NxN; adaptive reps until the timed window >= 50ms (or a rep cap). Returns MFLOP/s.
30func run_size(N: i64) -> i64 {
31 let A: *i64 = sys_mmap(N * N * 8) as *i64
32 let B: *i64 = sys_mmap(N * N * 8) as *i64
33 let C: *i64 = sys_mmap(N * N * 8) as *i64
34 let v: i64 = 0x3FC00000 // 1.5f
35 var i: i64 = 0
36 while i < N * N { A[i] = v; B[i] = v; i = i + 1 }
37 var reps: i64 = 1; var dt: i64 = 0; var go: i64 = 1
38 while go == 1 {
39 let t0: i64 = sys_now_ms()
40 var r: i64 = 0
41 while r < reps { nx_f32_matmul(A, B, C, N, N, N); r = r + 1 }
42 let t1: i64 = sys_now_ms()
43 dt = t1 - t0
44 if dt >= 50 { go = 0 } else { if reps >= K_MAGIC_8192 { go = 0 } else { reps = reps * 2 } }
45 }
46 if dt <= 0 { dt = 1 }
47 let macs: i64 = N * N * N * reps
48 let flops: i64 = 2 * macs
49 let mflops: i64 = flops / (dt * 1000)
50 let ns_per_mac: i64 = (dt * K_MAGIC_1000000) / macs
51 p_puts(" N="); p_putn(N); p_puts(" reps="); p_putn(reps); p_puts(" ms="); p_putn(dt)
52 p_puts(" MFLOP/s="); p_putn(mflops); p_puts(" ns/MAC="); p_putn(ns_per_mac); p_puts("\n")
53 return mflops
54}
55
56func main() -> i64 {
57 p_puts("=== sovereign f32 GEMM throughput (in-organ clock; bits-up f32, no FPU/SIMD/BLAS) ===\n")
58 run_size(32)
59 run_size(64)
60 run_size(128)
61 p_puts(" HONEST: this is OUR sovereign baseline. BLAS/cuBLAS NOT run (3rd-party, bench-lane);\n")
62 p_puts(" literature single-thread BLAS ~tens of GFLOP/s -> the gap = the simd/FPU lock (SPD-HW-VECTOR).\n")
63 sys_exit(0); return 0
64}