swiss ok, needs more benchmark

This commit is contained in:
Youmu Liu
2026-03-06 18:22:30 +08:00
parent 83997f64d0
commit f6e897ed06
70 changed files with 1889 additions and 3371 deletions
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.Await"
// Project: StgSharp
@@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
@@ -43,7 +44,9 @@ namespace StgSharp.Mathematics.Numeric
private static volatile int _createGeneration = 0;
private static int _sortState;
public static MatrixParallelThread[] LeadParallel(int recommendCount)
public static MatrixParallelThread[] LeadParallel(
int recommendCount
)
{
int min = int.Min(recommendCount, _threads.Capacity);
min /= 2;
@@ -108,7 +111,9 @@ namespace StgSharp.Mathematics.Numeric
// return ret;
}
public static void ReturnParallelResources(ref MatrixParallelThread[] pool)
public static void ReturnParallelResources(
ref MatrixParallelThread[] pool
)
{
while (true)
{
@@ -123,7 +128,11 @@ namespace StgSharp.Mathematics.Numeric
pool = null!;
}
private record class WaitHandle(int generation, int least, int best)
private record class WaitHandle(
int generation,
int least,
int best
)
{
public int CreateGeneration { get; init; } = generation;
@@ -135,7 +144,9 @@ namespace StgSharp.Mathematics.Numeric
public int Priority { get; private set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdatePriority(int currentGeneration)
public void UpdatePriority(
int currentGeneration
)
{
Priority = (currentGeneration - CreateGeneration) * (MatrixParallel._threads.Capacity - LeastCount);
}
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.AwaitingQueue"
// Project: StgSharp
@@ -51,19 +51,24 @@ namespace StgSharp.Mathematics.Numeric
public AwaitingQueue() { }
public void Enqueue(WaitHandle handle)
public void Enqueue(
WaitHandle handle
)
{
if (_count > 7)
{
_fallback.Enqueue(handle);
Interlocked.Increment(ref _count);
_ = Interlocked.Increment(ref _count);
return;
}
_quickElements[_count] = handle;
Interlocked.Increment(ref _count);
_ = Interlocked.Increment(ref _count);
}
public bool TryDequeue(int generation, out WaitHandle handle)
public bool TryDequeue(
int generation,
out WaitHandle handle
)
{
if (_count == 0)
{
@@ -83,7 +88,10 @@ namespace StgSharp.Mathematics.Numeric
return true;
}
public bool TryPeek(int generation, out WaitHandle handle)
public bool TryPeek(
int generation,
out WaitHandle handle
)
{
if (_count == 0)
{
@@ -99,7 +107,10 @@ namespace StgSharp.Mathematics.Numeric
return true;
}
public bool TryPopIfRefEqual(int generation, in WaitHandle handle)
public bool TryPopIfRefEqual(
int generation,
in WaitHandle handle
)
{
if (_count == 0) {
return false;
@@ -127,7 +138,9 @@ namespace StgSharp.Mathematics.Numeric
private WaitHandle value;
public static void Sort(ref Element e)
public static void Sort(
ref Element e
)
{
int maxIdx = 0;
WaitHandle first = e[0];
@@ -50,26 +50,22 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallelTask* package
)
{
switch (package->ComputeMode.OperationStyle)
{
case MatrixIndexStyle.BUFFER_INDEX:
return ScheduleBufferTask(package);
default:
throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}.");
}
return ScheduleBufferTask(package);
}
private static unsafe MatrixParallelWrap ScheduleBufferTask(
MatrixParallelTask* package
)
{
/*
int primCount = package->PrimCount;
int secCount = package->SecCount;
long count = (long)primCount * secCount;
/**/
// Console.WriteLine($"amount of kernels is {count}");
long recommendCount = count / 1024;
long recommendCount = /*count / /**/ 1024;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelWrap wrap = new MatrixParallelWrap(pool);
wrap.TaskQueue = MatrixParallelQueue.Rent(package);
@@ -1,106 +1,106 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Fma"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
internal static unsafe void ComputeFmaPanelF32(
MatrixParallelTask* p
)
{
int f32 = MatrixElementType.F32.IntrinsicNode;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Fma"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
internal static unsafe void ComputeFmaPanelF32(
MatrixParallelTask* p
)
{
int f32 = MatrixElementType.F32.IntrinsicNode;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
int commonK = p->LeftPrimOffset;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
enumeration->Member<int>(3) = ansHeight;
// in this occasion size must be 1
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
internal static unsafe void ComputeFmaPanelF64(
MatrixParallelTask* p
)
{
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
internal static unsafe void ComputeFmaPanelF64(
MatrixParallelTask* p
)
{
int f64 = MatrixElementType.F64.IntrinsicNode;
// int size = 1;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
int commonK = p->LeftPrimOffset;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
enumeration->Member<int>(3) = ansHeight;
// in this occasion size must be 1
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
}
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
}
}
@@ -1,76 +1,76 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Model"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
private const int KernelStealCount = 64;
internal unsafe void BufferCompute(
MatrixParallelTask* p
)
{
// while () { }
int size = p->ElementSize * 16;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
ScalarPacket* scalar = p->Scalar;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Model"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
private const int KernelStealCount = 64;
internal unsafe void BufferCompute(
MatrixParallelTask* p
)
{
// while () { }
int size = p->ElementSize * 16;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
ScalarPacket* scalar = p->Scalar;
IntPtr computeHandle = _context[p->ComputeHandle];
((delegate* unmanaged[Cdecl]<void*, void*, void*, void*, long, void>)computeHandle)((void*)(p->Left + offset),
(void*)(p->Right + offset),
(void*)(p->Answer + offset),
scalar,
count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void SpecialBufferCompute(
MatrixParallelTask* p
)
{
switch ((MatrixElementType)p->ElementSize)
{
case MatrixElementType.F64:
ComputeFmaPanelF64(p);
return;
case MatrixElementType.F32:
ComputeFmaPanelF32(p);
break;
default:
break;
}
}
}
((delegate* unmanaged[Cdecl]<void*, void*, void*, void*, long, void>)computeHandle)((void*)(p->Left + offset),
(void*)(p->Right + offset),
(void*)(p->Answer + offset),
scalar,
count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void SpecialBufferCompute(
MatrixParallelTask* p
)
{
switch ((MatrixElementType)p->ElementSize)
{
case MatrixElementType.F64:
ComputeFmaPanelF64(p);
return;
case MatrixElementType.F32:
ComputeFmaPanelF32(p);
break;
default:
break;
}
}
}
}
@@ -124,9 +124,11 @@ namespace StgSharp.Mathematics.Numeric
// Bind OS-thread affinity once when the worker starts running
SetThreadAffinity(PoolId);
Thread.Yield();
SIMDID feature = new();
feature.Mask = GetSimdId();
_ = Thread.Yield();
SIMDID feature = new()
{
Mask = GetSimdId()
};
_context = (nint*)MatrixParallel.GetContext(feature);
State = MatrixThreadState.Ready;
while (true)
@@ -148,6 +150,7 @@ namespace StgSharp.Mathematics.Numeric
{
MatrixParallelQueue taskQueue = BindedWrap.TaskQueue;
MatrixParallelTask* p = taskQueue.Package;
/*
if (0 > (int)p ->ComputeHandle) {
SpecialBufferCompute(p);
}
@@ -159,6 +162,7 @@ namespace StgSharp.Mathematics.Numeric
default:
break;
}
/**/
BindedWrap.ReportThreadAccomplished();
}
_managedThread.Priority = AfterWork;
@@ -98,9 +98,6 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallelTask* source
)
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
}
_wrapAllocator.Free((nuint)source);
}