add double compute kernel
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user