ARM NEON
NEON backend for VectorF32 on AArch64: one float32x4_t per vector (Len * Packing <= 4), with a vectorised sin/cos port of the SSE helpers. VectorF16 gets a native float16x8_t path when the target has ARMv8.2-FP16 arithmetic. Without it VectorF16 aliases VectorF32, which converts fp16 <-> fp32 on Load/Store. The scalar fallback gains the batched Dot that MatrixRowMajor relies on. Test tiers added for armv8-a and armv8.2-a+fp16. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
751a896d10
commit
0c55e76873
6 changed files with 825 additions and 17 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
A C++23 math library for the Crafter engine, distributed as a set of C++ modules. Provides generic vector and matrix types alongside SIMD-specialized fixed-size vectors for `float` and `_Float16`, plus a small set of ray intersection routines.
|
||||
|
||||
The library is hardware-aware: it picks the widest SIMD path the target supports (SSE / AVX / AVX-512 on x86_64, RVV on RISC-V, SIMD128 on WebAssembly) and falls back to scalar code elsewhere.
|
||||
The library is hardware-aware: it picks the widest SIMD path the target supports (SSE / AVX / AVX-512 on x86_64, NEON on AArch64, RVV on RISC-V, SIMD128 on WebAssembly) and falls back to scalar code elsewhere.
|
||||
|
||||
## Modules
|
||||
|
||||
|
|
@ -10,13 +10,13 @@ The library is hardware-aware: it picks the widest SIMD path the target supports
|
|||
|
||||
| Partition | Contents |
|
||||
| --- | --- |
|
||||
| `:Basic` | `ToRadian`, plus the `VectorF16 → VectorF32` alias on x86_64 without AVX512-FP16. |
|
||||
| `:Basic` | `ToRadian`, plus the `VectorF16 → VectorF32` alias on x86_64 without AVX512-FP16 and on AArch64 without ARMv8.2-FP16. |
|
||||
| `:Vector` | Generic `Vector<T, Len, Alignment>` with `.x/.y/.z/.w` and `.r/.g/.b/.a` accessors, arithmetic, comparison, and conversion operators. |
|
||||
| `:MatrixRowMajor` | `MatrixRowMajor<T, ColumnSize, RowSize, Repeats>` — row-major matrices with packed-batch support via `Repeats`. |
|
||||
| `:VectorF32` | `VectorF32<Len, Packing>` — SIMD-specialized 32-bit float vector with `Load`/`Store`, FMA, `Cross`, `Dot`, `Length`, `Normalize`, `Sin`/`Cos`, `Shuffle`, etc. |
|
||||
| `:VectorF16` | `VectorF16<Len, Packing>` — same surface as `VectorF32` for `_Float16` when the target supports it. |
|
||||
| `:Intersection` | `IntersectionTestRayTriangle`, `IntersectionTestRaySphere`, `IntersectionTestRayOrientedBox`. |
|
||||
| `:Common` | Internal SIMD type selection (`__m128/256/512`, `__m128h/256h/512h`, `v128_t`, or scalar array) used by the F16/F32 vectors. |
|
||||
| `:Common` | Internal SIMD type selection (`__m128/256/512`, `__m128h/256h/512h`, `float32x4_t`, `float16x8_t`, `v128_t`, or scalar array) used by the F16/F32 vectors. |
|
||||
|
||||
`Len` is the logical vector width (1–4 for most graphics use) and `Packing` is the number of vectors packed into one SIMD register — e.g. `VectorF32<3, 4>` holds four 3-vectors in a single 512-bit register, which is what the batched `Dot`, `Length`, and `Normalize` overloads operate on.
|
||||
|
||||
|
|
@ -52,6 +52,8 @@ This project uses [Crafter.Build](https://forgejo.catcrafts.net/Catcrafts/Crafte
|
|||
- `Vector-rv64gcv_zvl512b` — RVV with VLEN≥512 (uses the 64-byte tier)
|
||||
- `Vector-rv64gcv_zvl256b` — RVV with VLEN≥256 (32-byte tier)
|
||||
- `Vector-rv64gcv` — RVA23 baseline ZVL128B (16-byte tier)
|
||||
- `Vector-armv8.2-a+fp16` — AArch64 NEON with ARMv8.2-FP16 (native `VectorF16`)
|
||||
- `Vector-armv8-a` — AArch64 baseline NEON
|
||||
|
||||
Build and run tests via your usual Crafter.Build entry point; `build/` and `bin/` are git-ignored.
|
||||
|
||||
|
|
@ -59,6 +61,7 @@ Build and run tests via your usual Crafter.Build entry point; `build/` and `bin/
|
|||
|
||||
- **x86_64**: SSE / AVX / AVX-512F selected per target; AVX512-FP16 is required for native `VectorF16` (otherwise it aliases `VectorF32`). F16C is used for fp16 ↔ fp32 conversion when available.
|
||||
- **RISC-V**: RVV 1.0 (the `V` extension, ratified Nov 2021, mandatory in the RVA23 profile). Storage is a 16/32/64-byte GNU vector picked at compile time from the guaranteed VLEN (`__riscv_v_fixed_vlen` from Clang's `-mrvv-vector-bits=`, else `__riscv_v_min_vlen` from the march's `Zvl*` suffix, else the ZVL128B baseline). `VectorF16` aliases `VectorF32` until a `Zvfh` path lands.
|
||||
- **AArch64**: NEON (`arm_neon.h`) 128-bit path; SIMD width is capped at 16 bytes, so a vector holds at most 4 floats or 8 halves. `VectorF32` only needs the ARMv8-A baseline. ARMv8.2-FP16 (`-march=armv8.2-a+fp16`, or any `-march`/`-mcpu` that implies it) is required for native `VectorF16`; otherwise it aliases `VectorF32`, which converts fp16 ↔ fp32 on `Load`/`Store`. 32-bit ARM takes the scalar fallback.
|
||||
- **WebAssembly**: `wasm_simd128.h` 128-bit path; SIMD width is capped at 16 bytes.
|
||||
- **Other targets**: scalar fallback via `std::array<T, N>`.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue