Expand description
SIMD kernels behind the EdgeSimd trait.
The optimiser core (glm::levenberg) calls f64::dot_simd(..) and
f64::exp_in_place_simd(..) directly, since likelihoods and optimisers work
in f64 regardless of the crate’s T: EdgeFloat data layer. The vector width
lives here and nowhere else; no intrinsics or wide types appear outside
this file.
Each operation exists at four widths: scalar, 128-bit, 256-bit and 512-bit.
detect_simd_level caches what the machine supports and the trait impls
dispatch on it. A tier vectorises what it can at its own width, then hands
the remainder down to the tier below. That ladder matters here because the
hot caller is linear_predictor, which dots design rows of two to ten
elements: a single-width kernel would drop those straight to scalar.
The reductions run one accumulator, not several. Multiple accumulators break
the fadd dependency chain and pay from a few hundred elements up, but the
block loop that drives them needs lanes * accumulators elements before it
can fire at all, which at two to ten coefficients it never does. Dropping the
four-accumulator version moved glm_fit by under three per cent either way
at two and four coefficients and made it five per cent faster at eight, so it
was buying code and nothing else.
Enums§
- Simd
Level - Widest vector width available on the running machine.
Traits§
- Edge
Simd - SIMD-accelerated primitives over slices of a float type.
Functions§
- detect_
simd_ level - Detects the widest vector width this machine supports.