Measure the complete loop.

The standalone benchmark crate uses flyology_bench for warmup, calibration, balanced ordering, repeated samples, uncertainty, and diagnostics.

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_benchmark

Alire 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=scalar

Set 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.

Quiescence is evidence, not decoration

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.

BytesOrdinary AdaScalarStatic NEONRuntime
167.07 ns14.20 ns5.86 ns7.25 ns
4,0961,349.29 ns3,130.04 ns661.40 ns665.77 ns
1,048,576336,895 ns799,979 ns167,006 ns166,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.