Mandatory for all SIMD code in SharpCoreDB. Non-compliant code will be rejected in review.
All SIMD code MUST use the explicit intrinsics from System.Runtime.Intrinsics:
// ✅ REQUIRED — explicit multi-tier intrinsics
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
Vector512<float> v512 = Vector512.LoadUnsafe(ref data);
Vector256<float> v256 = Vector256.LoadUnsafe(ref data);
Vector128<float> v128 = Vector128.LoadUnsafe(ref data);DO NOT use the old portable Vector<T> from System.Numerics:
// ❌ BANNED — old portable SIMD (no explicit ISA control)
using System.Numerics;
Vector<float>.Count; // ❌
Vector.IsHardwareAccelerated; // ❌
MemoryMarshal.Cast<float, Vector<float>>(...); // ❌
Vector.Sum(...); // ❌As recommended by Tanner Gooding (.NET Runtime team), System.Runtime.Intrinsics is the
modern, preferred API for .NET 8+ / .NET 10:
| Feature | System.Numerics.Vector<T> (OLD) |
System.Runtime.Intrinsics (NEW) |
|---|---|---|
| ISA control | JIT decides width | Explicit per-tier |
| AVX-512 | No explicit support | Full Avx512F access |
| FMA | Not accessible | Fma.MultiplyAdd() |
| NativeAOT | Width may vary | Deterministic codegen |
| Instruction selection | Opaque | You choose the instruction |
| Multi-tier dispatch | Not possible | AVX-512 → AVX2 → SSE → Scalar |
Every SIMD hot path must implement a tiered fallback chain:
if (Avx512F.IsSupported && len >= AVX512_THRESHOLD)
{
// Vector512<T> path
}
else if (Avx2.IsSupported && len >= 8) // or Sse.IsSupported for float
{
// Vector256<T> path
}
else if (Sse.IsSupported && len >= 4) // or Sse2 for int/double
{
// Vector128<T> path
}
// Scalar tail — ALWAYS required
for (; i < len; i++) { /* scalar */ }| Data Type | 512-bit | 256-bit | 128-bit |
|---|---|---|---|
float |
Avx512F.IsSupported |
Avx2.IsSupported |
Sse.IsSupported |
double |
Avx512F.IsSupported |
Avx2.IsSupported |
Sse2.IsSupported |
int |
Avx512F.IsSupported |
Avx2.IsSupported |
Sse2.IsSupported |
long |
Avx512F.IsSupported |
Avx2.IsSupported |
Sse2.IsSupported |
byte (XOR/popcount) |
Avx512BW.IsSupported |
Avx2.IsSupported |
Sse2.IsSupported |
// ✅ DO — safe ref-based loading (no 'fixed', no unsafe)
ref float refData = ref MemoryMarshal.GetReference(span);
var vec = Vector256.LoadUnsafe(ref Unsafe.Add(ref refData, i));
// ✅ ALSO OK — pointer-based when already in unsafe context
var vec = Avx.LoadVector256(ptr + i);
// ❌ DON'T — old MemoryMarshal.Cast to Vector<T>
var vecs = MemoryMarshal.Cast<float, Vector<float>>(span);Always use FMA when available — better throughput AND precision:
// ✅ DO — FMA with fallback
if (Fma.IsSupported)
vSum = Fma.MultiplyAdd(va, vb, vSum); // a*b + c in one instruction
else
vSum += va * vb;
// ✅ DO — AVX-512 always has FMA
vSum = Avx512F.FusedMultiplyAdd(va, vb, vSum);// ✅ DO — cross-platform Vector*.Sum()
float result = Vector256.Sum(vAccumulator);
// ❌ DON'T — old System.Numerics
float result = Vector.Sum(vAccumulator);// ✅ DO
result.StoreUnsafe(ref Unsafe.Add(ref refDst, i));
// ❌ DON'T — old MemoryMarshal.Cast to write
var spanDst = MemoryMarshal.Cast<float, Vector<float>>(result.AsSpan());
spanDst[j] = value;AVX-512 has a frequency throttling cost on some CPUs. Use minimum element thresholds:
| Use Case | Minimum Elements |
|---|---|
| WHERE filtering (int/double) | 1024 |
| Distance metrics (float) | 64 |
| Batch XOR / Hamming | 32 bytes |
- WHERE filtering:
src/SharpCoreDB/Optimizations/SimdWhereFilter.cs - Distance metrics:
src/SharpCoreDB.VectorSearch/Distance/DistanceMetrics.cs - Hamming distance:
src/SharpCoreDB.VectorSearch/Quantization/BinaryQuantizer.cs
- No
System.Numerics.Vector<T>usage - No
Vector.IsHardwareAcceleratedchecks - Uses
Vector128<T>/Vector256<T>/Vector512<T>fromSystem.Runtime.Intrinsics - Multi-tier dispatch: AVX-512 → AVX2 → SSE → Scalar
- Scalar tail for remainder elements
- FMA used where available (
Fma.MultiplyAdd/Avx512F.FusedMultiplyAdd) -
[MethodImpl(MethodImplOptions.AggressiveOptimization)]on hot paths - AVX-512 guarded by minimum element threshold
The banned-API half of this standard is checked automatically:
pwsh -NoProfile -File tools/check-banned-simd-api.ps1 # scan the product sources
pwsh -NoProfile -File tools/check-banned-simd-api.ps1 -SelfTest # prove the detector itselftools/check-banned-simd-api.ps1 scans src/**/*.cs (never obj/ or bin/) for Vector<T>,
Vector.<member> and their System.Numerics-qualified forms, and exits non-zero when it finds one, so
a portable Vector<T> now fails the build instead of relying on a reviewer noticing it. Both
ci.yml (the primary pipeline on master, net11.0) and ci-net10.yml (the parked net10.0 line on
release/v2.0) run the self-test and the scan. The checker is comment- and string-aware,
which is why this file's own examples and the ban annotations in the sources do not trip it; anything
it suppresses is still printed as a note: line with the reason, so a suppressed line stays visible in
the log. using System.Numerics; itself stays legal — BitOperations lives there and is part of the
required mask-walk pattern.
The rest of this standard — the tier chain, the always-executed scalar tail, FMA, the AVX-512
thresholds, [MethodImpl(AggressiveOptimization)] — is not statically decidable and stays on the
review checklist above. A green checker is not a compliant kernel.
Enforcement: All new and modified SIMD code must comply. Existing violations should be migrated on contact.
Last Updated: 2026-09-26 (enforcement added; the requirements above are unchanged since 2025-07-08)