Iris SIMD Kernel Benchmark
Standalone, portable microbenchmark that measures whether Iris's SIMD (Java Vector API) kernels actually beat their scalar equivalents on the CPU it runs on. The Volmit dev/test machines are Apple Silicon, where the wide-SIMD path (4+ double lanes) does not exist. Copy the built artifact to a Windows/x86 box (AVX2 = 4 lanes, AVX-512 = 8 lanes) and run it to get real numbers for that CPU.
The six kernel classes are copied verbatim (logic byte-for-byte) from
Iris/core/.../util/simd/. This tool is intentionally a duplicate so it builds
and runs on its own with no Gradle, no VolmLib, and no Iris on the classpath.
Requirements
- JDK 25 (the tool is compiled with
--release 25). - The JDK must ship the
jdk.incubator.vectorincubator module (Temurin, Oracle, and all standard OpenJDK builds do).
How to run
Windows:
run.bat
macOS / Linux:
./run.sh
The run scripts compile the sources and create the ignored simd-bench.jar locally when it is
missing. Use build.bat or ./build.sh to rebuild it explicitly.
Or invoke directly (the --add-modules flag is required because the Vector API
is still an incubator module):
java --add-modules jdk.incubator.vector -jar simd-bench.jar
Mode flag
By default it runs both (scalar and vector head-to-head in one run). You can
also do a two-run A/B:
run.bat --mode scalar
run.bat --mode vector
run.bat --mode both (default)
--mode=scalar syntax works too. The correctness cross-check only runs in
both mode (it needs both implementations).
How to read the output
- Header prints the JVM,
os.arch, CPU count, and the preferred vector width.DoubleVector pref: N lanesis the SIMD width fordoubleon this CPU (2 on 128-bit NEON, 4 on AVX2, 8 on AVX-512). - noise SIMD gate (aligned && doubleLanes>=4) mirrors the real profitability
gate in Iris's
VectorNoiseKernels2D. It reports ENABLED on 4+ lane CPUs and DISABLED on 2-lane NEON. This tool ignores the gate and force-measures the raw vector kernel anyway, so you see the real number even where Iris would gate SIMD off. - Correctness cross-check runs each kernel once with both impls on identical
input and confirms they agree (roundToInt/noise are bit-exact;
sumdiffers only by floating-point reduction order, checked with a relative tolerance). If anything says MISMATCH, do not trust the timing numbers below it. - speedup = scalar ns/op / vector ns/op.
> 1.0means SIMD is faster on this CPU;< 1.0means SIMD is slower. Verdict column: SIMD FASTER / SIMD SLOWER / NEUTRAL (within ~5%). ns/opfor the array kernels is one full-array invocation (256 or 1024 doubles). For noise it is one 256-elementsimplexFractalFBMcall.- The trailing Checksum lines exist only to keep the JIT from deleting the measured work. Ignore their values.
Harness notes (why the numbers are trustworthy)
- Each op is warmed up 50,000 times before timing so the JIT has compiled the hot path.
- Every kernel output is folded into a running checksum (printed at the end) so no measured call is dead-code-eliminated.
- One input element is perturbed per iteration (a cheap store keyed off the loop counter) so the JIT cannot hoist a "constant" result out of the timing loop. This perturbation is identical for scalar and vector, so the comparison stays fair; it adds a tiny fixed cost to both sides that very slightly compresses the ratio on the cheapest kernels.
- Each (kernel, impl) is timed over 10 rounds; the minimum ns/op is reported (least-noisy statistic for a microbenchmark).
- Scalar and vector see the same seeded input for a given kernel.
Caveats
- This is an isolated-kernel vacuum microbench, not full worldgen. It says whether the raw kernel is faster on this CPU, not what end-to-end generation throughput will be (cache behavior, allocation, and surrounding code differ in the real engine).
- Effort 1 array kernels (
roundToInt/sum/max) run unconditionally in real Iris. Effort 2 noise (simplexFractalFBM) is currently unwired in Iris and gated to 4+ double lanes; this tool force-measures it regardless. - Vector-API auto-vectorization and cost depend heavily on the JDK version and CPU. Run on the actual target hardware; do not extrapolate across machines.