Background and motivation
We propose adding explicit low-level hardware intrinsics for high-performance CPU extensions that are currently missing from System.Runtime.Intrinsics.X86 and System.Runtime.Intrinsics.Arm.
This proposal targets three major CPU instruction domains:
-
Hardware Entropy / True Random Generation (RDRAND/RDSEED on x86, RNDR/RNDRRS on ARMv8.5-A FEAT_RNG):
Currently, .NET developers requiring hardware entropy must fallback to RandomNumberGenerator (P/Invoke to BCryptGenRandom or getrandom), which introduces unacceptable syscall and interop overhead in tight simulation loops (e.g., ray tracing, Monte Carlo simulations, or game engine procedural generation). Exposing direct processor hardware entropy registers allows sub-nanosecond random UInt64 generation with zero allocation.
-
Hardware Matrix Acceleration (AMX on Intel/AMD, SME/SME2 on ARMv9-A):
Modern high-performance compute workloads (on-device AI inference, 3D skeletal skinning, pathfinding, and physics) rely heavily on matrix multiplication ($A \times B + C$). While vector extensions (AVX-512, AVX10, SVE) process 1D vectors, AMX (x86 Tile registers) and SME (ARM Tile matrices) operate directly on 2D matrix tiles in hardware. Exposing these intrinsics gives C# game engines and native ML runtimes equal footing with C++/CUDA pipelines without native DllImport overhead.
-
Explicit APX API Exposure (Apx.IsSupported):
While .NET 10 introduced implicit JIT codegen support for Intel APX, exposing an explicit intrinsic class allows low-level developers to query support (Apx.IsSupported) and perform conditional branching for high-performance data structures.
API Proposal
namespace System.Runtime.Intrinsics.X86
{
// ==========================================
// 1. Hardware Random Number Generation (x86)
// ==========================================
public abstract class Rdrand : X86Base
{
public static new bool IsSupported { get; }
/// <summary>
/// Executes the RDRAND instruction to retrieve a hardware-generated random 16-bit value.
/// Returns false if hardware entropy pool was not ready (CF = 0).
/// </summary>
public static bool TryGetUInt16(out ushort result);
/// <summary>
/// Executes the RDRAND instruction to retrieve a hardware-generated random 32-bit value.
/// </summary>
public static bool TryGetUInt32(out uint result);
/// <summary>
/// Executes the RDRAND instruction to retrieve a hardware-generated random 64-bit value.
/// </summary>
public static bool TryGetUInt64(out ulong result);
}
public abstract class Rdseed : X86Base
{
public static new bool IsSupported { get; }
public static bool TryGetUInt16(out ushort result);
public static bool TryGetUInt32(out uint result);
public static bool TryGetUInt64(out ulong result);
}
// ==========================================
// 2. Advanced Matrix Extensions (AMX)
// ==========================================
public abstract class Amx : X86Base
{
public static new bool IsSupported { get; }
// Tile Configuration & Control
public static void TileConfig(ReadOnlySpan<byte> tilecfg);
public static void TileRelease();
// Tile Matrix Operations
public static void MultiplyAndAddBF16(byte dstTile, byte src1Tile, byte src2Tile);
public static void MultiplyAndAddInt8(byte dstTile, byte src1Tile, byte src2Tile);
// Tile Load & Store
public static unsafe void TileLoad(byte tile, void* baseAddress, nint stride);
public static unsafe void TileStore(byte tile, void* baseAddress, nint stride);
}
// ==========================================
// 3. Advanced Performance Extensions (APX)
// ==========================================
public abstract class Apx : X86Base
{
/// <summary>
/// Indicates whether Intel APX (Extended GPRs r16-r31, NDD 3-operand instructions) is supported.
/// </summary>
public static new bool IsSupported { get; }
}
}
namespace System.Runtime.Intrinsics.Arm
{
// ==========================================
// 1. Hardware Random Number Generation (ARMv8.5-A FEAT_RNG)
// ==========================================
public abstract class Rng : ArmBase
{
public static new bool IsSupported { get; }
/// <summary>
/// Executes 'MRS xt, RNDR' to read true hardware random number.
/// Returns false if hardware entropy pool was underflowed.
/// </summary>
public static bool TryGetUInt64(out ulong result);
/// <summary>
/// Executes 'MRS xt, RNDRRS' to read reseeded hardware random entropy source.
/// </summary>
public static bool TryGetEntropyUInt64(out ulong result);
}
// ==========================================
// 2. Scalable Matrix Extension (SME / SME2 - ARMv9-A)
// ==========================================
public abstract class Sme : ArmBase
{
public static new bool IsSupported { get; }
// Streaming Mode Controls
public static void EnterStreamingMode();
public static void ExitStreamingMode();
// Matrix Tile Operations (Outer Product & Accumulate)
public static void OuterProductAccumulate(byte tile, Vector128<float> vector1, Vector128<float> vector2);
public static void OuterProductSubtract(byte tile, Vector128<float> vector1, Vector128<float> vector2);
}
public abstract class Sme2 : Sme
{
public static new bool IsSupported { get; }
}
}
API Usage
using System;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.Arm;
public static class FastHardwareRandom
{
// Sub-nanosecond Random Generation with hardware cross-platform fallbacks
public static ulong GetNextUInt64()
{
if (Rdrand.IsSupported)
{
if (Rdrand.TryGetUInt64(out ulong val))
return val;
}
else if (Rng.IsSupported)
{
if (Rng.TryGetUInt64(out ulong val))
return val;
}
// Software Fallback
return (ulong)Random.Shared.Next64();
}
}
public static class MatrixComputeExample
{
public static void ExecuteMatrixMultiply()
{
if (Amx.IsSupported)
{
// Intel AMX tile multiplication path
// Amx.TileConfig(...);
// Amx.MultiplyAndAddBF16(0, 1, 2);
// Amx.TileRelease();
}
else if (Sme.IsSupported)
{
// ARM SME streaming mode matrix multiplication path
Sme.EnterStreamingMode();
// Sme.OuterProductAccumulate(...);
Sme.ExitStreamingMode();
}
}
}
Alternative Designs
-
RNG via System.Random / RandomNumberGenerator:
An alternative is modifying System.Random or RandomNumberGenerator to internally use RDRAND/RNDR when available. However, high-performance engines require fine-grained control over execution failure checking (evaluating returned boolean flags for CF/underflow) without the allocation and abstraction overhead of managed random generators.
-
Hiding Matrix Extensions behind System.Numerics.Tensors:
Another design is to only utilize AMX and SME inside high-level APIs like TensorPrimitives. While beneficial for high-level ML, game engine developers writing custom compute shaders, physics engines, or software rasterizers require direct hardware intrinsic access matching C++ intrinsics (<immintrin.h> / <arm_sme.h>).
Risks
-
Hardware / Microcode Quirks:
Early hardware implementations of RDRAND (e.g., specific older AMD microcodes) occasionally failed to replenish entropy pools under heavy contention. Returning a bool status (TryGetUInt64) directly mitigates this risk by allowing developers to safely fall back to software generators.
-
OS Context Switch Support for AMX/SME:
Both AMX and SME introduce significant new register states (Tile registers) that require OS kernel save/restore support (XSAVE on Windows/Linux for AMX, and streaming mode state management for SME). Amx.IsSupported and Sme.IsSupported must validate both CPUID flags AND OS kernel enablement flags (e.g., XCR0 bits) to prevent access violation crashes during context switches.
Background and motivation
We propose adding explicit low-level hardware intrinsics for high-performance CPU extensions that are currently missing from
System.Runtime.Intrinsics.X86andSystem.Runtime.Intrinsics.Arm.This proposal targets three major CPU instruction domains:
Hardware Entropy / True Random Generation (
RDRAND/RDSEEDon x86,RNDR/RNDRRSon ARMv8.5-A FEAT_RNG):Currently, .NET developers requiring hardware entropy must fallback to
RandomNumberGenerator(P/Invoke toBCryptGenRandomorgetrandom), which introduces unacceptable syscall and interop overhead in tight simulation loops (e.g., ray tracing, Monte Carlo simulations, or game engine procedural generation). Exposing direct processor hardware entropy registers allows sub-nanosecond random UInt64 generation with zero allocation.Hardware Matrix Acceleration ($A \times B + C$ ). While vector extensions (
AMXon Intel/AMD,SME/SME2on ARMv9-A):Modern high-performance compute workloads (on-device AI inference, 3D skeletal skinning, pathfinding, and physics) rely heavily on matrix multiplication (
AVX-512,AVX10,SVE) process 1D vectors,AMX(x86 Tile registers) andSME(ARM Tile matrices) operate directly on 2D matrix tiles in hardware. Exposing these intrinsics gives C# game engines and native ML runtimes equal footing with C++/CUDA pipelines without native DllImport overhead.Explicit APX API Exposure (
Apx.IsSupported):While .NET 10 introduced implicit JIT codegen support for Intel APX, exposing an explicit intrinsic class allows low-level developers to query support (
Apx.IsSupported) and perform conditional branching for high-performance data structures.API Proposal
namespace System.Runtime.Intrinsics.X86
{
// ==========================================
// 1. Hardware Random Number Generation (x86)
// ==========================================
public abstract class Rdrand : X86Base
{
public static new bool IsSupported { get; }
}
namespace System.Runtime.Intrinsics.Arm
{
// ==========================================
// 1. Hardware Random Number Generation (ARMv8.5-A FEAT_RNG)
// ==========================================
public abstract class Rng : ArmBase
{
public static new bool IsSupported { get; }
}
API Usage
using System;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.Arm;
public static class FastHardwareRandom
{
// Sub-nanosecond Random Generation with hardware cross-platform fallbacks
public static ulong GetNextUInt64()
{
if (Rdrand.IsSupported)
{
if (Rdrand.TryGetUInt64(out ulong val))
return val;
}
else if (Rng.IsSupported)
{
if (Rng.TryGetUInt64(out ulong val))
return val;
}
}
public static class MatrixComputeExample
{
public static void ExecuteMatrixMultiply()
{
if (Amx.IsSupported)
{
// Intel AMX tile multiplication path
// Amx.TileConfig(...);
// Amx.MultiplyAndAddBF16(0, 1, 2);
// Amx.TileRelease();
}
else if (Sme.IsSupported)
{
// ARM SME streaming mode matrix multiplication path
Sme.EnterStreamingMode();
// Sme.OuterProductAccumulate(...);
Sme.ExitStreamingMode();
}
}
}
Alternative Designs
RNG via
System.Random/RandomNumberGenerator:An alternative is modifying
System.RandomorRandomNumberGeneratorto internally useRDRAND/RNDRwhen available. However, high-performance engines require fine-grained control over execution failure checking (evaluating returned boolean flags for CF/underflow) without the allocation and abstraction overhead of managed random generators.Hiding Matrix Extensions behind
System.Numerics.Tensors:Another design is to only utilize
AMXandSMEinside high-level APIs likeTensorPrimitives. While beneficial for high-level ML, game engine developers writing custom compute shaders, physics engines, or software rasterizers require direct hardware intrinsic access matching C++ intrinsics (<immintrin.h>/<arm_sme.h>).Risks
Hardware / Microcode Quirks:
Early hardware implementations of
RDRAND(e.g., specific older AMD microcodes) occasionally failed to replenish entropy pools under heavy contention. Returning aboolstatus (TryGetUInt64) directly mitigates this risk by allowing developers to safely fall back to software generators.OS Context Switch Support for AMX/SME:
Both
AMXandSMEintroduce significant new register states (Tile registers) that require OS kernel save/restore support (XSAVEon Windows/Linux for AMX, and streaming mode state management for SME).Amx.IsSupportedandSme.IsSupportedmust validate both CPUID flags AND OS kernel enablement flags (e.g.,XCR0bits) to prevent access violation crashes during context switches.