exploratory · off the HST main path

HST as a local execution-node runtime layer

Put HST lower in the stack as a user-space runtime layer inside a fully sandboxed Linux VM, then measure whether sparse workloads can be transparently routed through it — instead of being called by hand from one demo.

Host
Apple M1 Max · arm64
macOS 26.3 · 10 core · 68 GB
Sandbox
Ubuntu 24.04 arm64
Multipass · Virtualization.framework
Profiler
Linux perf stat
ARM/NEON — no AVX/VTune path

Three execution paths, identical stream

baseline_csc — exact CSC reuse-delta every step. The honest sparse baseline.

library_hst — rebuild an HST schedule every step, then apply. Naive "call HST by hand": pays schedule-build cost on every update.

runtime_hst — a node that caches schedules keyed by the dirty-tile-set and gates by density. The caller just submit()s updates; the node decides HST-vs-CSC. This is the runtime layer.

Result — N=M=60k, fill=0.45, 2000 steps

dirty patterndensitybaseline_csclibrary_hstruntime_hstruntime / library
scattered640.0431.8 ms1175.8 ms31.2 ms37.7×
one_tile321.0025.0 ms65.2 ms28.5 ms2.29×
four_tiles321.0042.1 ms169.0 ms52.8 ms3.20×
eight_tiles321.0058.7 ms281.7 ms80.8 ms3.49×

The runtime layer recovers ~all of CSC's performance (it routes scattered updates away from HST) while running 2.3–37.7× faster than naive library-HST calls. The schedule cache is the whole point of putting HST in the stack as a runtime instead of a manual call.

In the sandboxed VM (Ubuntu 24.04 arm64, Multipass)

Same workload, run inside the isolated guest — the pattern holds (build cost varies with guest scheduling):

dirty patternbaseline_csclibrary_hstruntime_hstruntime / library
scattered6431.8 ms1579.5 ms35.5 ms44.6×
one_tile3224.8 ms77.2 ms33.0 ms2.34×
four_tiles3245.9 ms230.5 ms65.2 ms3.54×
eight_tiles3264.2 ms371.0 ms94.3 ms3.94×
perf stat (guest, software events)
task-clock 1770 ms · context-switches 5 · cpu-migrations 0 · major-faults 0 · minor-faults 47.7k — CPU-bound and fully in-memory, as intended. Hardware PMU counters (cycles/cache/branch) report <not supported> — Apple Virtualization.framework does not expose the ARM PMU to the guest. That's the honest ceiling of profiling inside this sandbox; hardware counters need bare-metal Linux.

Where HST has to go: batch size

At batch=1 the tile kernel's per-row overhead isn't amortized, so HST loses. Widen the batch (process B state vectors per step) and it crosses over. eight_tiles32, fill=0.60, in-process:

batch Bcschst (in-proc)hst / cscverdict
140.1 ms46.5 ms0.86×HST loses
257.2 ms53.5 ms1.07×crossover
4108.0 ms82.2 ms1.31×HST wins
8204.2 ms138.5 ms1.47×HST wins
16365.2 ms227.8 ms1.60×HST wins

The win grows with batch size, with the number of dirty tiles (one_tile32 tops out ~1.1×; eight_tiles32 reaches 1.6×), and with fill. This scalar kernel leaves more on the table — explicit SIMD across the batch lane is the next step toward the ~2.5× ceiling. Direction: HST needs B≥2 to break even, B≥4 to matter, and wide batches + dense tile-local updates to shine.

The cost of calling home

The in-process runtime just reads and writes the caller's arrays. Put HST behind a boundary (RPC / REST / separate process) and every step must marshal the dirty input across and the touched output back. Below is that marshalling floor — real memcpy in + out, the cheapest any such design can be. Real IPC adds syscalls and scheduling on top.

batch Bhst in-proc / cschst call-home / cscthe tax
10.86×0.74×a loss becomes a bigger loss
41.31×1.13×−14% of the win
161.60×1.49×−7% of the win

Marshalling hurts most exactly where HST is weakest (small batches — copy dominates compute). The takeaway: the win only exists in-process. A version of HST that "calls home" every step cannot realize it; the boundary has to be crossed rarely (batch the work) or not at all (link it in).

Honest constraints

In-process only. A daemon / IPC / REST front destroys the sub-millisecond win. The "node" is a linked library, not a service.

Batch=1 doesn't beat CSC. HST loses at B=1 and needs B≥2 to break even (measured above); the win widens with batch size, dirty-tile count, and fill, toward a ~2.5× ceiling with SIMD.

User-space only. No BIOS, kernel drivers, bootloader, or host process injection — matches the tasking guardrails.