add double compute kernel

This commit is contained in:
Youmu Liu
2025-12-26 17:16:12 +08:00
parent e5539bcc6d
commit c6d53d97ea
16 changed files with 821 additions and 300 deletions
+28 -21
View File
@@ -61,17 +61,9 @@ namespace StgSharp.HighPerformance
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ElementSideLength<T>() where T : unmanaged, INumber<T>
{
return Math.Max(8, AlignmentBytes / sizeof(T));
return PanelSideLength<T>();
}
// View an existing pointer; caller guarantees lifetime/alignment.
public static unsafe MatrixPanel<T>* FromPointer<T>(void* ptr)
where T : unmanaged, INumber<T>
{
return (MatrixPanel<T>*)Align64(ptr);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int MaxElementCount<T>() where T : unmanaged, INumber<T>
{
int side = ElementSideLength<T>();
@@ -115,28 +107,43 @@ namespace StgSharp.HighPerformance
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountAvx2<T>() where T : unmanaged, INumber<T>
{
const int minQ = 8;
int lanes = 32 / sizeof(T);
int side = Math.Max(lanes, minQ);
return side / 4;
return PanelSideFromBits<T>(256) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountAvx512<T>() where T : unmanaged, INumber<T>
{
const int minQ = 8;
int lanes = 64 / sizeof(T);
int side = Math.Max(lanes, minQ);
return side / 4;
return PanelSideFromBits<T>(512) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountSse<T>() where T : unmanaged, INumber<T>
{
const int minQ = 4;
int lanes = 16 / sizeof(T);
int side = Math.Max(lanes, minQ);
return side / 4;
return PanelSideFromBits<T>(128) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideFromBits<T>(int vectorBits) where T : unmanaged, INumber<T>
{
int elemBits = sizeof(T) * 8;
// Q = max(4, vectorBits/64, vectorBits/elemBits)
int by64 = vectorBits / 64;
int byElem = vectorBits / elemBits;
int side = Math.Max(4, Math.Max(by64, byElem));
return side;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideLength<T>() where T : unmanaged, INumber<T>
{
return NativeIntrinsic.IntrinsicLevel switch
{
IntrinsicLevel.SSE => PanelSideFromBits<T>(128),
IntrinsicLevel.AVX2 => PanelSideFromBits<T>(256),
IntrinsicLevel.AVX512 => PanelSideFromBits<T>(512),
_ => 0
};
}
}
@@ -39,20 +39,29 @@ namespace StgSharp.Internal.Intrinsic
{
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify; //city_hash_simplify
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_buffer_add; //f32_buffer_add
public delegate* unmanaged[Cdecl]<void*, ScalarPacket*,long, void> f32_buffer_fill; //f32_buffer_fill
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> f32_buffer_scalar_mul; //f32_buffer_s_m
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_buffer_sub; //f32_kernel_sub
public delegate* unmanaged[Cdecl]<void*, void*, void> f32_buffer_transpose; //f32_kernel_transpose
public delegate* unmanaged[Cdecl]<MatrixPanel*, MatrixKernel*, int, int, int, int, void> f32_build_panel; //f32_build_panel
public delegate* unmanaged[Cdecl]<MatrixPanel*, void> f32_clear_panel;
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> f32_normalize_3; //f32_normalize_3
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_panel_fma; //f32_panel_fma
public delegate* unmanaged[Cdecl]<void*, ulong, ulong, ulong, void> f32_pivot; //f32_panel_mul
public delegate* unmanaged[Cdecl]<void*, void*, int, int, int, int, void> f32_store_panel; //f32_store_panel
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd; //factorial_simd
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair; //index_pair
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> variant ; //variant
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> mat_f32_buffer_add; //f32_buffer_add
public delegate* unmanaged[Cdecl]<void*, ScalarPacket*, long, void> mat_f32_buffer_fill; //f32_buffer_fill
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> mat_f32_buffer_scalar_mul; //f32_buffer_s_m
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> mat_f32_buffer_sub; //f32_kernel_sub
public delegate* unmanaged[Cdecl]<void*, void*, void> mat_f32_buffer_transpose; //f32_kernel_transpose
public delegate* unmanaged[Cdecl]<MatrixPanel*, MatrixKernel*, int, int, int, int, void> mat_f32_build_panel; //f32_build_panel
public delegate* unmanaged[Cdecl]<MatrixPanel*, void> mat_f32_clear_panel; //f32_clear_panel
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> mat_f32_panel_fma; //f32_panel_fma
public delegate* unmanaged[Cdecl]<void*, ulong, ulong, ulong, void> mat_f32_pivot; //f32_panel_mul
public delegate* unmanaged[Cdecl]<void*, void*, int, int, int, int, void> mat_f32_store_panel; //f32_store_panel
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> mat_f64_buffer_add; //f32_buffer_add
public delegate* unmanaged[Cdecl]<void*, ScalarPacket*, long, void> mat_f64_buffer_fill; //f32_buffer_fill
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> mat_f64_buffer_scalar_mul; //f32_buffer_s_m
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> mat_f64_buffer_sub; //f32_kernel_sub
public delegate* unmanaged[Cdecl]<void*, void*, void> mat_f64_buffer_transpose; //f32_kernel_transpose
public delegate* unmanaged[Cdecl]<MatrixPanel*, MatrixKernel*, int, int, int, int, void> mat_f64_build_panel; //f32_build_panel
public delegate* unmanaged[Cdecl]<MatrixPanel*, void> mat_f64_clear_panel; //f32_clear_panel
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> mat_f64_panel_fma; //f32_panel_fma
public delegate* unmanaged[Cdecl]<void*, ulong, ulong, ulong, void> mat_f64_pivot; //f32_panel_mul
public delegate* unmanaged[Cdecl]<void*, void*, int, int, int, int, void> mat_f64_store_panel; //f32_store_panel
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> vec_f32_normalize_3; //f32_normalize_3
public IntrinsicContext()
{
@@ -169,7 +169,7 @@ namespace StgSharp.Mathematics.Graphic
internal unsafe void InternalTranspose(ref Matrix44 transpose)
{
fixed (MatrixKernel<float>* source = &this.kernel, target = &transpose.kernel) {
NativeIntrinsic.Context.f32_buffer_transpose(source, target);
NativeIntrinsic.Context.mat_f32_buffer_transpose(source, target);
}
}
@@ -177,7 +177,7 @@ namespace StgSharp.Mathematics.Graphic
public static unsafe Matrix44 operator -(Matrix44 left, Matrix44 right)
{
Matrix44 ret = new();
NativeIntrinsic.Context.f32_buffer_sub(&left, &right, &ret, 1);
NativeIntrinsic.Context.mat_f32_buffer_sub(&left, &right, &ret, 1);
return ret;
}
@@ -219,7 +219,7 @@ namespace StgSharp.Mathematics.Graphic
public static unsafe Matrix44 operator +(Matrix44 left, Matrix44 right)
{
Matrix44 ret = new();
NativeIntrinsic.Context.f32_buffer_add(&left, &right, &ret, 1);
NativeIntrinsic.Context.mat_f32_buffer_add(&left, &right, &ret, 1);
return ret;
}
+47 -5
View File
@@ -50,14 +50,17 @@ namespace StgSharp.Mathematics.Numeric
MatrixSize size,
MatrixStorage<T> buffer
)
)
{
_boarder = boarder;
_size = size;
_buffer = buffer;
}
public T this[int x, int y]
public T this[
int x,
int y
]
{
get
{
@@ -108,7 +111,8 @@ namespace StgSharp.Mathematics.Numeric
/// </exception>
public unsafe Matrix<T> this[
ReadOnlySpan<MatrixIndex> column,
ReadOnlySpan<MatrixIndex> row]
ReadOnlySpan<MatrixIndex> row
]
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
@@ -137,7 +141,10 @@ namespace StgSharp.Mathematics.Numeric
protected internal int KernelRowLength => _size.KernelRowLength;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe ref MatrixKernel<T> GetMatrixKernel(int x, int y)
public unsafe ref MatrixKernel<T> GetMatrixKernel(
int x,
int y
)
{
MatrixKernelEnumerator enumerator = new(_size.KernelColumnLength, _size.KernelRowLength,
x, y);
@@ -147,7 +154,10 @@ namespace StgSharp.Mathematics.Numeric
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref T GetElementUnsafe(int x, int y)
internal unsafe ref T GetElementUnsafe(
int x,
int y
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y >> 2;
@@ -161,5 +171,37 @@ namespace StgSharp.Mathematics.Numeric
return ref kernel[c, r];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe MatrixKernel<T>* GetKernelAddressUnsafe(
int x,
int y
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y >> 2;
int k_r = x >> 2;
MatrixKernelEnumerator enumerator = new(_size.KernelColumnLength, _size.KernelRowLength,
k_c, k_r);
return Buffer + _boarder.GetIndexOffset(k_c, k_r, in enumerator);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref MatrixKernel<T> GetKernelUnsafe(
int x,
int y
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y >> 2;
int k_r = x >> 2;
int c = y & 3;
int r = x & 3;
MatrixKernelEnumerator enumerator = new(_size.KernelColumnLength, _size.KernelRowLength,
k_c, k_r);
return ref _buffer[_boarder.GetIndexOffset(k_c, k_r, in enumerator)];
}
}
}