Run the benchmark crate
The Flyology_SIMD library keeps zero runtime dependencies. The separate benchmark crate depends on flyology_bench and the local SIMD crate.
cd benchmarks
alr build --release
FLYOLOGY_BENCH_OUTPUT=terminal alr run --skip-build simd_benchmarkAlire detects AArch64 or x86-64 from the host. Use the scalar GPR scenario when you need a scalar-only comparison.
alr build --release -- -XFLYOLOGY_SIMD_ARCH=scalarSet FLYOLOGY_BENCH_OUTPUT to csv or json for machine-readable output. Keep generated results outside version control or under benchmark-results/.
Control measurement error
The program calls Flyology_Bench.Compare_Many. Each comparison uses a 250 ms warmup, equal-time calibration, 75 balanced samples, and three seconds of measurement.
The report retains raw samples and computes bootstrap confidence intervals. It also reports candidate-order effects and lag-one correlation. The benchmark does not silently discard outliers or subtract estimated timer cost.
A validation checksum prevents dead-code elimination. The report also records the compiler version, project switches, selected backend, and CPU features.
Set FLYOLOGY_BENCH_QUIESCENCE=1 to wait for a quiet host. Set FLYOLOGY_SIMD_BENCH_CPU when the host supports CPU pinning. Record any control that the host could not apply.
Compare boundary and streaming sizes
The cases use 7, 15, 16, 17, 4,096, and 1,048,576 bytes. These sizes expose setup cost, every side of the 16-byte boundary, cache-resident work, and larger streaming work.
Each case compares an ordinary Ada loop, the scalar backend, the statically selected native backend, and coarse runtime dispatch. The test measures complete algorithms rather than isolated vector primitives.
Read local observations with their limits
On 2026-08-10, an Apple Mac15,9 AArch64 host with GNAT FSF 16.1.0 produced the following medians. Library objects used -O2 -ftree-vectorize, and benchmark code used -O3.
| Bytes | Ordinary Ada | Scalar | Static NEON | Runtime |
|---|---|---|---|---|
| 16 | 7.07 ns | 14.20 ns | 5.86 ns | 7.25 ns |
| 4,096 | 1,349.29 ns | 3,130.04 ns | 661.40 ns | 665.77 ns |
| 1,048,576 | 336,895 ns | 799,979 ns | 167,006 ns | 166,945 ns |
Below one vector, the ordinary loop wins because setup and tail work dominate. At 4 KiB and 1 MiB, both NEON paths win in this run.
An earlier result incorrectly showed the Ada loop winning for large buffers. The complete imported algorithm loop lacked optimization. Verbose compiler commands exposed the mismatch, and the GPR now applies -O2 to all library units.
Do not generalize one result
A small median or a narrow confidence interval does not remove systematic bias. Repeat the run, retain its diagnostics, inspect generated code, and report the complete environment before making a performance claim.
Use the Flyology benchmarking guide for the statistical method. The repository's docs/benchmarking.md records the current AArch64 and x86-64 observations in full.