better kernel fma
This commit is contained in:
@@ -46,13 +46,17 @@ namespace StgSharp.HighPerformance
|
||||
return (MatrixPanel<T>*)NativeMemory.AlignedAlloc(Size<T>(), AlignmentBytes);
|
||||
}
|
||||
|
||||
public static unsafe void Destroy<T>(MatrixPanel<T>* panel) where T : unmanaged, INumber<T>
|
||||
public static unsafe void Destroy<T>(
|
||||
MatrixPanel<T>* panel
|
||||
) where T : unmanaged, INumber<T>
|
||||
{
|
||||
NativeMemory.AlignedFree(panel);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static unsafe Span<T> Elements<T>(ref T head) where T : unmanaged, INumber<T>
|
||||
public static unsafe Span<T> Elements<T>(
|
||||
ref T head
|
||||
) where T : unmanaged, INumber<T>
|
||||
{
|
||||
void* p = Unsafe.AsPointer(ref head);
|
||||
return new Span<T>(p, MaxElementCount<T>());
|
||||
@@ -92,17 +96,26 @@ namespace StgSharp.HighPerformance
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static int KernelSideCount<T>() where T : unmanaged, INumber<T>
|
||||
{
|
||||
return NativeIntrinsic.IntrinsicLevel switch
|
||||
SIMDID id = NativeIntrinsic.IntrinsicMask;
|
||||
switch (id.MaskByte[0] & 0b_00001111)
|
||||
{
|
||||
IntrinsicLevel.SSE => KernelSideCountSse<T>(),
|
||||
IntrinsicLevel.AVX2 => KernelSideCountAvx2<T>(),
|
||||
IntrinsicLevel.AVX512 => KernelSideCountAvx512<T>(),
|
||||
_ => 0
|
||||
};
|
||||
case 1:
|
||||
return id.MaskByte[1] switch
|
||||
{
|
||||
1 => KernelSideCountSse<T>(),
|
||||
2 => KernelSideCountAvx2<T>(),
|
||||
3 => KernelSideCountAvx512<T>(),
|
||||
_ => throw new NotSupportedException("Unsupported SIMD level."),
|
||||
};
|
||||
default:
|
||||
throw new NotSupportedException("Current hardware platform is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static unsafe nuint Align64(void* p) => ((nuint)p + (AlignmentBytes - 1)) & ~(nuint)(AlignmentBytes - 1);
|
||||
private static unsafe nuint Align64(
|
||||
void* p
|
||||
) => ((nuint)p + (AlignmentBytes - 1)) & ~(nuint)(AlignmentBytes - 1);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int KernelSideCountAvx2<T>() where T : unmanaged, INumber<T>
|
||||
@@ -123,7 +136,9 @@ namespace StgSharp.HighPerformance
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int PanelSideFromBits<T>(int vectorBits) where T : unmanaged, INumber<T>
|
||||
private static int PanelSideFromBits<T>(
|
||||
int vectorBits
|
||||
) where T : unmanaged, INumber<T>
|
||||
{
|
||||
int elemBits = sizeof(T) * 8;
|
||||
|
||||
@@ -137,13 +152,20 @@ namespace StgSharp.HighPerformance
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int PanelSideLength<T>() where T : unmanaged, INumber<T>
|
||||
{
|
||||
return NativeIntrinsic.IntrinsicLevel switch
|
||||
SIMDID id = NativeIntrinsic.IntrinsicMask;
|
||||
switch (id.MaskByte[0] & 0b_00001111)
|
||||
{
|
||||
IntrinsicLevel.SSE => PanelSideFromBits<T>(128),
|
||||
IntrinsicLevel.AVX2 => PanelSideFromBits<T>(256),
|
||||
IntrinsicLevel.AVX512 => PanelSideFromBits<T>(512),
|
||||
_ => 0
|
||||
};
|
||||
case 1:
|
||||
return id.MaskByte[1] switch
|
||||
{
|
||||
1 => PanelSideFromBits<T>(128),
|
||||
2 => PanelSideFromBits<T>(256),
|
||||
3 => PanelSideFromBits<T>(512),
|
||||
_ => throw new NotSupportedException("Unsupported SIMD level."),
|
||||
};
|
||||
default:
|
||||
throw new NotSupportedException("Current hardware platform is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -154,7 +176,10 @@ namespace StgSharp.HighPerformance
|
||||
|
||||
internal T Head; // first element of the panel buffer
|
||||
|
||||
public ref T this[int column, int row]
|
||||
public ref T this[
|
||||
int column,
|
||||
int row
|
||||
]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => ref Unsafe.Add(ref Head, row * MatrixPanel.ElementSideLength<T>() + column);
|
||||
|
||||
Reference in New Issue
Block a user