Large task publish ok

This commit is contained in:
Youmu Liu
2025-10-24 16:20:21 +08:00
parent 4d142a4365
commit 1c9b820531
4 changed files with 227 additions and 197 deletions
@@ -42,21 +42,22 @@ namespace StgSharp.Mathematics.Numeric
nint l = p->Left, r = p->Right, a = p->Result; nint l = p->Left, r = p->Right, a = p->Result;
long long
// set beginning value to counters for primary offsets // set beginning value to counters for primary offsets
lCount = (long)p->LeftPrimOffset * p->LeftPrimStride, lCount = (long)p->LeftPrimOffset * p->LeftPrimStride,
rCount = (long)p->RightPrimOffset * p->RightPrimStride, rCount = (long)p->RightPrimOffset * p->RightPrimStride,
aCount = (long)p->ResultPrimOffset * p->ResultPrimStride, aCount = (long)p->ResultPrimOffset * p->ResultPrimStride,
pCount = p->PrimCount, pCount = int.Min(p->PrimCount, p->PrimColumnCountInTile + p->PrimTileOffset)/*count of tile may be too much*/,
//edge to reset counters //edge to reset counters
lLimit = pCount - p->LeftPrimOffset, lLimit = pCount - p->LeftPrimOffset,
rLimit = pCount - p->RightPrimOffset, rLimit = pCount - p->RightPrimOffset,
aLimit = pCount - p->ResultPrimOffset; aLimit = pCount - p->ResultPrimOffset;
delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void> op = delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void> op =
(delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void>)p->ComputeHandle; (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void>)p->ComputeHandle;
for (long i = 0; i < pCount; i++) for (long i = p->PrimTileOffset; i < pCount; i++)
{ {
// update primary counters // update primary counters
// if reachs edge, reset to zero // if reaches edge, reset to zero
lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0; lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0;
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0; rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0; aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
@@ -69,12 +70,12 @@ namespace StgSharp.Mathematics.Numeric
lc = (long)p->LeftSecOffset * p->LeftSecStride, lc = (long)p->LeftSecOffset * p->LeftSecStride,
rc = (long)p->RightSecOffset * p->RightSecStride, rc = (long)p->RightSecOffset * p->RightSecStride,
ac = (long)p->ResultSecOffset * p->ResultSecStride, ac = (long)p->ResultSecOffset * p->ResultSecStride,
sCount = p->SecCount; sCount = int.Min(p->SecCount, p->SecColumnCountInTile + p->SecTileOffset);
long long
ll = sCount - p->LeftSecOffset, ll = sCount - p->LeftSecOffset,
rl = sCount - p->RightSecOffset, rl = sCount - p->RightSecOffset,
al = sCount - p->ResultSecOffset; al = sCount - p->ResultSecOffset;
for (int j = 0; j < sCount; j++) for (int j = p->SecTileOffset; j < sCount; j++)
{ {
lc = j < ll ? lc + p->LeftSecOffset : 0; lc = j < ll ? lc + p->LeftSecOffset : 0;
rc = j < rl ? rc + p->RightSecOffset : 0; rc = j < rl ? rc + p->RightSecOffset : 0;
@@ -818,44 +818,66 @@ namespace StgSharp.Mathematics.Numeric
int primCount = package->PrimCount; int primCount = package->PrimCount;
int secCount = package->SecCount; int secCount = package->SecCount;
int tileWidth = (1024 / secCount) + 1; int tileWidth = (1024 / secCount) + 1;
int tileCount = (primCount / tileWidth) + 1; int tileCount = (primCount + tileWidth - 1) / tileWidth;
MatrixParallelPool pool = LeadParallel(); MatrixParallelPool pool = LeadParallel();
int tilePerThreadLess = tileCount / pool.SpareThreadCount; int threadCount = pool.SpareThreadCount;
int tileToSlice = tileCount % pool.SpareThreadCount; int tilePerThreadLess = tileCount / threadCount; // tiles per thread without extra slice
int slicingPerWrap = tileToSlice / pool.SpareThreadCount; int columnAfterBaseTile = tileCount % threadCount * tileWidth; // tile sliced into columns
int extraTiles = tileToSlice % pool.SpareThreadCount; int extraColumnPerThread = columnAfterBaseTile / threadCount;
int extraColumnCount = columnAfterBaseTile % threadCount; // columns to be sliced
int total = tileCount; int total = primCount;
int begin = 0; Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(pool.SpareThreadCount); MatrixParallelTaskPackage<T>* current = package;
while (tileCount > 0) while (true)
{ {
_ = pool.TryRequestWrap(out MatrixParallelWrap? wrap); if (!pool.TryRequestWrap(out MatrixParallelWrap? wrap) || wrap is null)
bool hasSlice = tileToSlice > 0; {
bool isLargeSlice = extraTiles > 0; #if DEBUG
throw new InvalidOperationException("Someone steal parallel wraps from the pool.");
#endif
}
bool hasSlice = columnAfterBaseTile > 0;
bool isLargeSlice = extraColumnCount > 0;
// count tiles for wrap // count tiles for wrap
// TODO 此处应该是线程数量而不是线程束数量 int wrapWidth = wrap!.WrapTaskCapacity;
// TODO 需要想办法正确同步线程数量信息 int columnFromSlicingCount = (hasSlice ? extraColumnPerThread : 0) * wrapWidth;
int toSlice = hasSlice ? wrap!.WrapTaskCapacity * slicingPerWrap : 0; int baseColumn = wrapWidth * tilePerThreadLess * tileWidth;
int baseTile = wrap!.WrapTaskCapacity * tilePerThreadLess; int columnInWrap = baseColumn + columnFromSlicingCount + (isLargeSlice ? 1 : 0);
int tileInWrap = baseTile + toSlice + (isLargeSlice ? 1 : 0);
int columnInWrap = tileInWrap * tileWidth;
// set tasks // set tasks
MatrixParallelTaskPackage<T>* task = MatrixParallelFactory.FromExistPackage(package); if (columnInWrap == 0)
wrap.WrapTask = (MatrixParallelTaskPackageNonGeneric*)task; {
task->LeftPrimOffset += columnInWrap; #if DEBUG
task->PrimCount = columnInWrap; throw new InvalidOperationException("Zero tasks published.");
#endif
}
// update current task
current->PrimColumnCountInTile = columnInWrap;
current->SecColumnCountInTile = current->SecCount;
current->SecTileBegin = 0;
// remove tiles count // remove tiles count
extraTiles--; extraColumnCount--;
tileToSlice -= toSlice; columnAfterBaseTile -= columnFromSlicingCount;
tileCount -= tileInWrap; total -= columnInWrap;
begin += tileInWrap;
// set to wrap and push
wrap.WrapTask = (MatrixParallelTaskPackageNonGeneric*)current;
taskBunch.Push(wrap); taskBunch.Push(wrap);
if (total <= 0)
{
break;
}
current = MatrixParallelFactory.FromExistPackage(current);
current->PrimTileBegin += columnInWrap;
} }
ReleaseParallelLeadership(ref pool); ReleaseParallelLeadership(ref pool);
@@ -1,30 +1,27 @@
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="MatrixParallelPool.cs" // file="MatrixParallelPool"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload Space // AuthorGroup: Nitload
// Copyright (c) Nitload Space. All rights reserved. // Copyright (c) Nitload. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person obtaining a copy
// obtaining a copy of this software and associated documentation // of this software and associated documentation files (the "Software"), to deal
// files (the “Software”), to deal in the Software without restriction, // in the Software without restriction, including without limitation the rights
// including without limitation the rights to use, copy, modify, merge, // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// publish, distribute, sublicense, and/or sell copies of the Software, // copies of the Software, and to permit persons to whom the Software is
// and to permit persons to whom the Software is furnished to do so, // furnished to do so, subject to the following conditions:
// subject to the following conditions:
// //
// The above copyright notice and // The above copyright notice and this permission notice shall be included in all
// this permission notice shall be included in all copies // copies or substantial portions of the Software.
// or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED “AS IS”, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// ARISING FROM, OUT OF OR IN CONNECTION WITH // SOFTWARE.
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -33,6 +30,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -99,6 +97,7 @@ namespace StgSharp.Mathematics.Numeric
return false; return false;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryRequestWrap([NotNull] out MatrixParallelWrap? wrap) public bool TryRequestWrap([NotNull] out MatrixParallelWrap? wrap)
{ {
if (SpareWrap.TryPop(out wrap)) if (SpareWrap.TryPop(out wrap))
@@ -114,10 +114,12 @@ namespace StgSharp.Mathematics.Numeric
#endregion #endregion
#region reserve #region count offset
public readonly long ReservedLong0; // 8 public readonly int PrimTileOffset; // 4
public readonly long ReservedLong1; // 8 public readonly int SecTileOffset; // 4
public readonly int PrimColumnCountInTile; // 4
public readonly int SecColumnCountInTile; // 4
#endregion #endregion
} }
@@ -134,7 +136,11 @@ namespace StgSharp.Mathematics.Numeric
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Copy(MatrixParallelTaskPackage<T>* source, MatrixParallelTaskPackage<T>* target) public static unsafe void Copy(MatrixParallelTaskPackage<T>* source, MatrixParallelTaskPackage<T>* target)
{ {
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage<T>), sizeof(MatrixParallelTaskPackage<T>)); Buffer.MemoryCopy(
source,
target,
sizeof(MatrixParallelTaskPackage<T>),
sizeof(MatrixParallelTaskPackage<T>));
} }
#region source #region source
@@ -197,10 +203,12 @@ namespace StgSharp.Mathematics.Numeric
#endregion #endregion
#region reserve #region count offset
public long ReservedLong0; // 8 public int PrimTileBegin; // 4
public long ReservedLong1; // 8 public int SecTileBegin; // 4
public int PrimColumnCountInTile; // 4
public int SecColumnCountInTile; // 4
#endregion #endregion
} }