Something went wrong. Try again.
strata but optimized for m5 (and maybe more later)
Something went wrong. Try again.
regolith bench
7 files
m5_air_microbench_v2.m
m5_air_microbench_v3.m
m5_air_microbench.m
README.md
run_01_m5_air_microbench.log
README.md
Phase 0 Hardware Microbench — 13" MacBook Air M5 (Mac17,3) #
experiment: measure real uncached NVMe SSD throughput across MoE expert read patterns
(3x512 KiB std GGUF vs 1x1.5 MiB contiguous .experts copy, queue depth 1..8,
and 4 KiB PLE n-gram row lookups) plus M5 10-core GPU FP16 GEMM ceiling and
60-second fanless thermal sag, to replace the 3 vs 6 GB/s and ~360 tok/s
estimates in PLAN.md §5.2.
runs:
- run_01: bench/m5_air_microbench.m -> bench/run_01_m5_air_microbench.log
- run_02: bench/m5_air_microbench_v2.m -> bench/run_02_m5_air_microbench_v2.log
(strictly disjoint offsets, F_NOCACHE=0 RAM control, 60s GPU thermal sag)
- run_03: bench/m5_air_microbench_v3.m -> bench/run_03_m5_air_microbench_v3.log
(12 GiB virgin slices, every test verified 100.0% physical NVMe via `iostat -Id` disk0)
execution: /usr/bin/clang -O3 -fobjc-arc -framework Foundation -framework Metal
-framework MetalPerformanceShaders -lpthread; macOS 27.0 arm64, Apple M5
(4S+6E CPU, 10-core GPU, 24 GB unified memory, 1 TB SSD).
decision: answered. PLAN.md §2.5, §4.3, and §5.2 updated with measured constants and
two new runtime squeezes (2-4 thread pread fan-out for experts; 8-thread
batched pread for layer-2 PLE 4 KiB row lookups).
Key Measurements #
1. SSD Read Throughput (run_03, 100.0% disk0 hardware counter verified on virgin 1 GiB slices) #
| Pattern | Read size | th=1 (QD1) |
th=2 |
th=4 |
th=8 |
|---|---|---|---|---|---|
| Sequential ceiling | 4 MiB | 5.49 GB/s | — | 7.09 GB/s | — |
| Standard GGUF (3 reads/expert, random) | 512 KiB | 2.41 GB/s | 5.52 GB/s | 7.03 GB/s | 7.04 GB/s |
Contiguous .experts copy (1 read/expert, random) |
1.5 MiB | 3.93 GB/s | 6.84 GB/s | 6.89 GB/s | 6.66 GB/s |
Prefill strided ascending (.experts copy) |
1.5 MiB | 3.85 GB/s | — | 6.60 GB/s | — |
PLE n-gram table random 4 KiB (run_01) |
4 KiB | 0.04 GB/s (~10k IOPS, ~1.6 ms/tok for 16 heads) | — | — | 0.33 GB/s (~82k IOPS, ~0.2 ms/tok) |
Control: cached RAM (F_NOCACHE=0, run_02) |
512 KiB | 25.59 GB/s | — | 45.70 GB/s | — |
Methodological catch during run_02 → run_03:
On macOS APFS, repeating pread over the exact same file offsets across loop iterations can partially hit APFS cache on iteration 2+ even when the descriptor has F_NOCACHE=1. run_03 eliminated this by allocating a 12 GiB file of unique incompressible blocks, giving every single test its own virgin 1 GiB slice, and verifying iostat -Id (disk0 physical MiB delta == 100.0% of requested MiB) around each test.
2. M5 10-Core GPU FP16 GEMM & 60-Second Thermal Sag (run_01, run_02) #
MTLDevice:Apple M5,hasUnifiedMemory = 1,recommendedMaxWorkingSetSize = 17.76 GiB- Peak burst FP16 GEMM (
K = 2560):M = 512, N = 2560: 12.60 TFLOP/sM = 1024, N = 2560: 13.66 TFLOP/sM = 4096, N = 2560: 14.07 TFLOP/s (exactly 1/4 of the 40-core M5 Max's ~56 TFLOP/s, confirming the ~356–360 tok/s resident prefill compute ceiling at ~30.4% MFU)
- 60-second continuous 100% GPU load (
M = 4096, K = 2560, N = 2560FP16 GEMM):t = 0..15s: 14.00–14.03 TFLOP/st = 30..35s: 13.98 TFLOP/st = 55..60s: 13.88 TFLOP/s (−0.86% sag over 60 seconds; the 10-core M5 GPU does not thermally cliff inside a 1-minute window).