add scheduler method; fixing buffer parallel errors
This commit is contained in:
@@ -93,7 +93,8 @@ namespace StgSharp.Collections
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public T[] PopRange(int count)
|
public T[] PopRange(int count)
|
||||||
{
|
{
|
||||||
int i = int.Min(count, _index) - 1;
|
int i = int.Min(count, _index);
|
||||||
|
_index -= i;
|
||||||
return _values[0..i];
|
return _values[0..i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,8 +148,7 @@ namespace StgSharp.Collections
|
|||||||
public static CapacityFixedStack<T> Create<T>(ReadOnlySpan<T> values)
|
public static CapacityFixedStack<T> Create<T>(ReadOnlySpan<T> values)
|
||||||
{
|
{
|
||||||
CapacityFixedStack<T> stack = new(values.Length);
|
CapacityFixedStack<T> stack = new(values.Length);
|
||||||
Span<T> sp = stack.GetValueLayout();
|
stack.PushRange(values);
|
||||||
values.CopyTo(sp);
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
MatrixParallel.ReturnParallelResources(ref pool);
|
MatrixParallel.ReturnParallelResources(ref pool);
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
MatrixParallelTaskPackage<float>* package = MatrixParallelFactory.CreateBaseTask<float>();
|
MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask<float>();
|
||||||
package->Left = left.Buffer;
|
package->Left = (nint)left.Buffer;
|
||||||
package->Right = right.Buffer;
|
package->Right = (nint)right.Buffer;
|
||||||
package->Result = ans.Buffer;
|
package->Result = (nint)ans.Buffer;
|
||||||
package->ElementSize = sizeof(float);
|
package->ElementSize = sizeof(float);
|
||||||
package->PrimCount = left.KernelColumnLength;
|
package->PrimCount = left.KernelColumnLength;
|
||||||
package->SecCount = left.KernelRowLength;
|
package->SecCount = left.KernelRowLength;
|
||||||
@@ -80,41 +80,37 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||||
|
|
||||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||||
/*
|
|
||||||
* run parallel
|
|
||||||
*/
|
|
||||||
MatrixParallelFactory.Release(package);
|
|
||||||
taskGroup.Dispose();
|
taskGroup.Dispose();
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe void Fill<T>(this Matrix<float> right, T value) where T : unmanaged, INumber<T>
|
public static unsafe void Fill<T>(this Matrix<float> ans, T value) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
long count = (long)right.KernelColumnLength * right.KernelRowLength;
|
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
|
||||||
ScalarPacket* scaler = MatrixParallelFactory.CreateScalarPacket();
|
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
|
||||||
scaler->Data<T>(0) = value;
|
scalar->Data<T>(0) = value;
|
||||||
if (count <= 256)
|
if (count <= 256)
|
||||||
{
|
{
|
||||||
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, count);
|
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
|
||||||
return;
|
return;
|
||||||
} else if (count <= 1024)
|
} else if (count <= 1024)
|
||||||
{
|
{
|
||||||
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
|
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
|
||||||
|
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
|
||||||
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, count);
|
|
||||||
|
|
||||||
MatrixParallel.ReturnParallelResources(ref pool);
|
MatrixParallel.ReturnParallelResources(ref pool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MatrixParallelHandle taskGroup =/**/ default
|
MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask<float>();
|
||||||
/*MatrixParallel.PublicNoAnswerTask(left.GetColumnEnumeration(), scaler,
|
package->Result = (nint)ans.Buffer;
|
||||||
(delegate* unmanaged[Cdecl]<MatrixKernel<float>*, ScalarPacket*, void>)NativeIntrinsic.Intrinsic.f32_add)
|
package->ElementSize = sizeof(float);
|
||||||
/**/;
|
package->PrimCount = ans.KernelColumnLength;
|
||||||
|
package->SecCount = ans.KernelRowLength;
|
||||||
|
package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.ANS_SCALAR_PARAM);
|
||||||
|
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_fill;
|
||||||
|
package->Scalar = scalar;
|
||||||
|
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||||
/*
|
|
||||||
* run parallel
|
|
||||||
*/
|
|
||||||
MatrixParallelFactory.Release(scaler);
|
|
||||||
taskGroup.Dispose();
|
taskGroup.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,31 +34,33 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
internal static class MatrixComputeModel
|
internal static class MatrixComputeModel
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static unsafe void BufferComputeBinary(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void BufferComputeBinary(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int size = p->ElementSize * 16;
|
int size = p->ElementSize * 16;
|
||||||
int count = p->PrimCount * p->SecCount;
|
long count = Unsafe.As<int, long>(ref p->PrimCount);
|
||||||
int offset = p->LeftPrimOffset * p->SecCount;
|
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
|
||||||
|
|
||||||
((delegate* unmanaged[Cdecl]<void*, void*, void*, int, void>)p->ComputeHandle)((void*)(p->Left + offset * size),
|
((delegate* unmanaged[Cdecl]<void*, void*, void*, long, void>)p->ComputeHandle)((void*)(p->Left + offset),
|
||||||
(void*)(p->Right + offset * size),
|
(void*)(p->Right + offset),
|
||||||
(void*)(p->Result + offset * size),
|
(void*)(p->Result + offset),
|
||||||
count);
|
count);
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static unsafe void BufferComputeUnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void BufferComputeUnaryScalar(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int size = p->ElementSize * 16;
|
int size = p->ElementSize * 16;
|
||||||
int count = p->PrimCount * p->SecCount;
|
long count = Unsafe.As<int, long>(ref p->PrimCount);
|
||||||
int offset = p->LeftPrimOffset * p->SecCount;
|
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
|
||||||
|
|
||||||
((delegate* unmanaged[Cdecl]<void*, void*, int, void>)p->ComputeHandle)((void*)(p->Right + offset * size),
|
((delegate* unmanaged[Cdecl]<void*, void*, long, void>)p->ComputeHandle)((void*)(p->Right + offset),
|
||||||
(void*)(p->Result + offset * size),
|
(void*)(p->Result + offset),
|
||||||
count);
|
count);
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_Binary(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void Compute_Binary(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int eSize = p->ElementSize;
|
int eSize = p->ElementSize;
|
||||||
|
|
||||||
@@ -106,10 +108,11 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac);
|
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int eSize = p->ElementSize;
|
int eSize = p->ElementSize;
|
||||||
|
|
||||||
@@ -157,10 +160,11 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac, p->Scalar);
|
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac, p->Scalar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_Unary(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void Compute_Unary(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int eSize = p->ElementSize;
|
int eSize = p->ElementSize;
|
||||||
|
|
||||||
@@ -201,10 +205,11 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
op(right + (nint)rc, ans + (nint)ac);
|
op(right + (nint)rc, ans + (nint)ac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackage* p)
|
||||||
{
|
{
|
||||||
int eSize = p->ElementSize;
|
int eSize = p->ElementSize;
|
||||||
|
|
||||||
@@ -245,6 +250,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
op(right + (nint)rc, ans + (nint)ac, p->Scalar);
|
op(right + (nint)rc, ans + (nint)ac, p->Scalar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MatrixParallelFactory.Release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,14 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
public static partial class MatrixParallel
|
public static partial class MatrixParallel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private const int MIN_TASK_PER_THREAD = 256;
|
||||||
|
private const int REC_TASK_PER_THREAD = 1024;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|
||||||
internal static unsafe MatrixParallelHandle ScheduleTask<T>(MatrixParallelTaskPackage<T>* package)
|
internal static unsafe MatrixParallelHandle ScheduleTask(MatrixParallelTaskPackage* package)
|
||||||
where T : unmanaged,INumber<T>
|
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackageNonGeneric* nonGeneric = (MatrixParallelTaskPackageNonGeneric*)package;
|
MatrixParallelTaskPackage* nonGeneric = package;
|
||||||
switch (nonGeneric->ComputeMode.OperationStyle)
|
switch (nonGeneric->ComputeMode.OperationStyle)
|
||||||
{
|
{
|
||||||
case MatrixOperationStyle.PANEL_OP:
|
case MatrixOperationStyle.PANEL_OP:
|
||||||
@@ -60,12 +62,46 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static unsafe MatrixParallelHandle ScheduleBufferTask(MatrixParallelTaskPackageNonGeneric* package)
|
private static unsafe MatrixParallelHandle ScheduleBufferTask(MatrixParallelTaskPackage* package)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
int primCount = package->PrimCount;
|
||||||
|
int secCount = package->SecCount;
|
||||||
|
long count = (long)primCount * secCount;
|
||||||
|
|
||||||
|
long recommendCount = count / 1024;
|
||||||
|
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
|
||||||
|
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
|
||||||
|
if (handle.Wraps.Count() == 1)
|
||||||
|
{
|
||||||
|
ref long offsetRef = ref Unsafe.As<int, long>(ref package->PrimTileOffset);
|
||||||
|
offsetRef = 0;
|
||||||
|
ref long lengthRef = ref Unsafe.As<int, long>(ref package->PrimCount);
|
||||||
|
lengthRef = count;
|
||||||
|
handle.Wraps.First().WrapTask.Enqueue((nint)package);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
long actual = count / pool.Length;
|
||||||
|
long extra = count % pool.Length;
|
||||||
|
|
||||||
|
long offset = 0;
|
||||||
|
MatrixParallelTaskPackage* current = package;
|
||||||
|
foreach (MatrixParallelWrap wrap in handle.Wraps)
|
||||||
|
{
|
||||||
|
long wrapTaskLength = actual * wrap.WrapTaskCapacity;
|
||||||
|
long ex = Math.Min(extra, wrap.WrapTaskCapacity);
|
||||||
|
extra -= ex;
|
||||||
|
ref long offsetRef = ref Unsafe.As<int, long>(ref current->PrimTileOffset);
|
||||||
|
offsetRef = offset;
|
||||||
|
ref long lengthRef = ref Unsafe.As<int, long>(ref current->PrimCount);
|
||||||
|
lengthRef = wrapTaskLength + ex;
|
||||||
|
wrap.WrapTask.Enqueue((nint) current);
|
||||||
|
current = MatrixParallelFactory.FromExistPackage(current);
|
||||||
|
offset += wrapTaskLength;
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static unsafe MatrixParallelHandle ScheduleKernelTask(MatrixParallelTaskPackageNonGeneric* package)
|
private static unsafe MatrixParallelHandle ScheduleKernelTask(MatrixParallelTaskPackage* package)
|
||||||
{
|
{
|
||||||
int primCount = package->PrimCount;
|
int primCount = package->PrimCount;
|
||||||
int secCount = package->SecCount;
|
int secCount = package->SecCount;
|
||||||
@@ -73,17 +109,17 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
int tileCount = (primCount + tileWidth - 1) / tileWidth;
|
int tileCount = (primCount + tileWidth - 1) / tileWidth;
|
||||||
|
|
||||||
MatrixParallelThread[] pool = LeadParallel(tileCount);
|
MatrixParallelThread[] pool = LeadParallel(tileCount);
|
||||||
|
/*
|
||||||
if (pool.Length == 0)
|
if (pool.Length == 0)
|
||||||
{
|
{
|
||||||
/*
|
// no need
|
||||||
* wait until has enough threads
|
// LeadParallel has contained capacity check
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
/**/
|
||||||
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
|
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
|
||||||
if (handle.Wraps.Count() == 1)
|
if (handle.Wraps.Count() == 1)
|
||||||
{
|
{
|
||||||
handle.Wraps.First().WrapTask = package;
|
handle.Wraps.First().WrapTask.Enqueue((nint)package);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
int threadCount = pool.Length;
|
int threadCount = pool.Length;
|
||||||
@@ -94,7 +130,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
int total = primCount;
|
int total = primCount;
|
||||||
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
|
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
|
||||||
MatrixParallelTaskPackageNonGeneric* current = package;
|
MatrixParallelTaskPackage* current = package;
|
||||||
foreach (MatrixParallelWrap wrap in handle.Wraps)
|
foreach (MatrixParallelWrap wrap in handle.Wraps)
|
||||||
{
|
{
|
||||||
bool hasSlice = columnAfterBaseTile > 0;
|
bool hasSlice = columnAfterBaseTile > 0;
|
||||||
@@ -127,7 +163,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
total -= columnInWrap;
|
total -= columnInWrap;
|
||||||
|
|
||||||
// set to wrap and push
|
// set to wrap and push
|
||||||
wrap.WrapTask = current;
|
wrap.WrapTask.Enqueue((nint)current);
|
||||||
|
|
||||||
if (total <= 0)
|
if (total <= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
RemainThreadCount = _threads.Count;
|
RemainThreadCount = _threads.Count;
|
||||||
_AfterWork = (ThreadPriority)afterWork;
|
_AfterWork = (ThreadPriority)afterWork;
|
||||||
foreach (MatrixParallelWrap w in handle.Wraps) {
|
foreach (MatrixParallelWrap w in handle.Wraps) {
|
||||||
w.SchedulerReset.Set();
|
w.SetScheduler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// file="MatrixParallelPool"
|
// file="MatrixParallelHandle"
|
||||||
// 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 obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -39,7 +39,8 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
public struct MatrixParallelHandle : IDisposable
|
public struct MatrixParallelHandle : IDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
private static readonly (int a, int b)[] LookupTable = [ (1, 1), // 7
|
private static readonly (int a, int b)[] LookupTable = [
|
||||||
|
(1, 1), // 7
|
||||||
(0, 2), // 8 (no non-zero solution)
|
(0, 2), // 8 (no non-zero solution)
|
||||||
(3, 0), // 9 (no non-zero solution)
|
(3, 0), // 9 (no non-zero solution)
|
||||||
(2, 1), // 10
|
(2, 1), // 10
|
||||||
@@ -157,6 +158,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
{
|
{
|
||||||
MatrixParallelWrap wrap = new MatrixParallelWrap(_threads, 0, count);
|
MatrixParallelWrap wrap = new MatrixParallelWrap(_threads, 0, count);
|
||||||
_wraps = [ wrap ];
|
_wraps = [ wrap ];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
(int c3,int c4) = FastDecompose(_threads.Length);
|
(int c3,int c4) = FastDecompose(_threads.Length);
|
||||||
_wraps = new(c3 + c4);
|
_wraps = new(c3 + c4);
|
||||||
|
|||||||
@@ -82,16 +82,13 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit, Size = 128)]
|
[StructLayout(LayoutKind.Explicit, Size = 128)]
|
||||||
internal unsafe struct MatrixParallelTaskPackageNonGeneric
|
public unsafe struct MatrixParallelTaskPackage
|
||||||
{
|
{
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static unsafe void Copy(
|
public static unsafe void Copy(MatrixParallelTaskPackage* source, MatrixParallelTaskPackage* target)
|
||||||
MatrixParallelTaskPackageNonGeneric* source,
|
|
||||||
MatrixParallelTaskPackageNonGeneric* target)
|
|
||||||
{
|
{
|
||||||
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackageNonGeneric),
|
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage), sizeof(MatrixParallelTaskPackage));
|
||||||
sizeof(MatrixParallelTaskPackageNonGeneric));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region source
|
#region source
|
||||||
@@ -113,7 +110,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
#region left enum
|
#region left enum
|
||||||
|
|
||||||
[FieldOffset(32)] public int LeftPrimOffset; // 4
|
[FieldOffset(32)]public int LeftPrimOffset; // 4
|
||||||
[FieldOffset(36)]public int LeftPrimStride; // 4
|
[FieldOffset(36)]public int LeftPrimStride; // 4
|
||||||
[FieldOffset(40)]public int LeftSecOffset; // 4
|
[FieldOffset(40)]public int LeftSecOffset; // 4
|
||||||
[FieldOffset(44)]public int LeftSecStride; // 4
|
[FieldOffset(44)]public int LeftSecStride; // 4
|
||||||
@@ -122,7 +119,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
#region right enum
|
#region right enum
|
||||||
|
|
||||||
[FieldOffset(32)] public int RightPrimOffset; // 4
|
[FieldOffset(32)]public int RightPrimOffset; // 4
|
||||||
[FieldOffset(36)]public int RightPrimStride; // 4
|
[FieldOffset(36)]public int RightPrimStride; // 4
|
||||||
[FieldOffset(40)]public int RightSecOffset; // 4
|
[FieldOffset(40)]public int RightSecOffset; // 4
|
||||||
[FieldOffset(44)]public int RightSecStride; // 4
|
[FieldOffset(44)]public int RightSecStride; // 4
|
||||||
@@ -147,9 +144,9 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
#region global profile
|
#region global profile
|
||||||
|
|
||||||
[FieldOffset(96)]public int PrimCount; // 4
|
[FieldOffset(96)]public int PrimCount; // 4
|
||||||
[FieldOffset(100)]public MatrixOpMode ComputeMode; // 4
|
[FieldOffset(100)]public int SecCount; // 4
|
||||||
[FieldOffset(104)]public int SecCount; // 4
|
[FieldOffset(104)]public MatrixOpMode ComputeMode; // 4
|
||||||
[FieldOffset(108)]private int ReservedInt0; // 4
|
[FieldOffset(108)]private int ReservedInt0; // 4
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -163,90 +160,4 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit, Size =128)]
|
|
||||||
internal unsafe struct MatrixParallelTaskPackage<T> where T : unmanaged, INumber<T>
|
|
||||||
{
|
|
||||||
|
|
||||||
public MatrixParallelTaskPackage()
|
|
||||||
{
|
|
||||||
Unsafe.SkipInit(out this);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static unsafe void Copy(MatrixParallelTaskPackage<T>* source, MatrixParallelTaskPackage<T>* target)
|
|
||||||
{
|
|
||||||
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage<T>),
|
|
||||||
sizeof(MatrixParallelTaskPackage<T>));
|
|
||||||
}
|
|
||||||
|
|
||||||
#region source
|
|
||||||
|
|
||||||
// Group 1: Left/Right matrix kernel base address
|
|
||||||
[FieldOffset(0)]public MatrixKernel<T>* Left; // 8
|
|
||||||
[FieldOffset(8)] public MatrixKernel<T>* Right; // 8
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ans
|
|
||||||
|
|
||||||
// Group 2: Result kernel base address + reserved
|
|
||||||
[FieldOffset(16)] public MatrixKernel<T>* Result; // 8
|
|
||||||
[FieldOffset(24)] public int ElementSize = sizeof(T);
|
|
||||||
[FieldOffset(28)] public int ReservedPtr0; // 4 (extension/reserved)
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region left enum
|
|
||||||
|
|
||||||
[FieldOffset(32)]public int LeftPrimOffset; // 4
|
|
||||||
[FieldOffset(36)]public int LeftPrimStride; // 4
|
|
||||||
[FieldOffset(40)]public int LeftSecOffset; // 4
|
|
||||||
[FieldOffset(44)] public int LeftSecStride; // 4
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region right enum
|
|
||||||
|
|
||||||
[FieldOffset(48)]public int RightPrimOffset; // 4
|
|
||||||
[FieldOffset(52)]public int RightPrimStride; // 4
|
|
||||||
[FieldOffset(56)]public int RightSecOffset; // 4
|
|
||||||
[FieldOffset(60)]public int RightSecStride; // 4
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ans enum
|
|
||||||
|
|
||||||
[FieldOffset(64)]public int ResultPrimOffset; // 4
|
|
||||||
[FieldOffset(68)]public int ResultPrimStride; // 4
|
|
||||||
[FieldOffset(72)]public int ResultSecOffset; // 4
|
|
||||||
[FieldOffset(76)] public int ResultSecStride; // 4
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region scalar/compute
|
|
||||||
|
|
||||||
[FieldOffset(80)] public ScalarPacket* Scalar; // 8
|
|
||||||
[FieldOffset(88)]public IntPtr ComputeHandle; // 8
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region global profile
|
|
||||||
|
|
||||||
[FieldOffset(96)] public int PrimCount; // 4
|
|
||||||
[FieldOffset(100)]public MatrixOpMode ComputeMode; // 4
|
|
||||||
[FieldOffset(104)]public int SecCount; // 4
|
|
||||||
[FieldOffset(108)] private readonly int ReservedInt0; // 4
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region count offset
|
|
||||||
|
|
||||||
[FieldOffset(112)]public int PrimTileOffset; // 4
|
|
||||||
[FieldOffset(116)]public int SecTileOffset; // 4
|
|
||||||
[FieldOffset(120)]public int PrimColumnCountInTile; // 4
|
|
||||||
[FieldOffset(124)]public int SecColumnCountInTile; // 4
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -53,6 +54,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
_affinity = AffinityAllocator.Allocate();
|
_affinity = AffinityAllocator.Allocate();
|
||||||
|
|
||||||
_managedThread = new Thread(MatrixParallelWorker);
|
_managedThread = new Thread(MatrixParallelWorker);
|
||||||
|
_managedThread.Start();
|
||||||
_resetEvent = new ManualResetEventSlim(false);
|
_resetEvent = new ManualResetEventSlim(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
{
|
{
|
||||||
while (taskQueue.TryDequeue(out nint handle))
|
while (taskQueue.TryDequeue(out nint handle))
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackageNonGeneric* p = (MatrixParallelTaskPackageNonGeneric*)handle;
|
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)handle;
|
||||||
switch (p->ComputeMode.OperationStyle)
|
switch (p->ComputeMode.OperationStyle)
|
||||||
{
|
{
|
||||||
case MatrixOperationStyle.PANEL_OP:
|
case MatrixOperationStyle.PANEL_OP:
|
||||||
@@ -127,16 +129,12 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Restart()
|
public void Restart()
|
||||||
{
|
{
|
||||||
_resetEvent.Set();
|
_resetEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReturnToPool()
|
|
||||||
{
|
|
||||||
// MatrixParallel.(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!disposedValue)
|
if (!disposedValue)
|
||||||
@@ -159,27 +157,30 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
// Bind OS-thread affinity once when the worker starts running
|
// Bind OS-thread affinity once when the worker starts running
|
||||||
ApplyAffinityIfNeeded();
|
ApplyAffinityIfNeeded();
|
||||||
|
|
||||||
// Thread self = Thread.CurrentThread;
|
while (true)
|
||||||
_resetEvent.Wait();
|
|
||||||
_resetEvent.Reset();
|
|
||||||
_managedThread.Priority = ThreadPriority.Highest;
|
|
||||||
switch (Role)
|
|
||||||
{
|
{
|
||||||
case 0://worker
|
// Thread self = Thread.CurrentThread;
|
||||||
// _ = Interlocked.Decrement(ref RemainThreadCount);
|
_managedThread.Priority = ThreadPriority.Highest;
|
||||||
ExecuteTaskPackage(Tasks);
|
_resetEvent.Wait();
|
||||||
break;
|
_resetEvent.Reset();
|
||||||
case 1://scheduler
|
switch (Role)
|
||||||
BindedWrap.PublishTaskToWorkers(Tasks);
|
{
|
||||||
BindedWrap.SetAllWorker();
|
case 0://worker
|
||||||
ExecuteTaskPackage(Tasks);
|
// _ = Interlocked.Decrement(ref RemainThreadCount);
|
||||||
break;
|
ExecuteTaskPackage(Tasks);
|
||||||
case 2://leader, error because leader should be at outer thread but not here
|
break;
|
||||||
break;
|
case 1://scheduler
|
||||||
default:
|
BindedWrap.PublishTaskToWorkers(BindedWrap.WrapTask);
|
||||||
break;
|
BindedWrap.SetAllWorker();
|
||||||
|
ExecuteTaskPackage(Tasks);
|
||||||
|
break;
|
||||||
|
case 2://leader, error because leader should be at outer thread but not here
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_managedThread.Priority = AfterWork;
|
||||||
}
|
}
|
||||||
_managedThread.Priority = AfterWork;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region core affinity
|
#region core affinity
|
||||||
|
|||||||
@@ -44,10 +44,13 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
internal MatrixParallelWrap(MatrixParallelThread[] threads, int begin, int count)
|
internal MatrixParallelWrap(MatrixParallelThread[] threads, int begin, int count)
|
||||||
{
|
{
|
||||||
|
WrapTaskCapacity = count;
|
||||||
_threads = threads;
|
_threads = threads;
|
||||||
_begin = begin;
|
_begin = begin;
|
||||||
Count = threads.Length;
|
|
||||||
_threads[_begin].Role = 1;
|
_threads[_begin].Role = 1;
|
||||||
|
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
|
||||||
|
_threads[i].BindedWrap = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatrixParallelWrap()
|
public MatrixParallelWrap()
|
||||||
@@ -63,15 +66,11 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
internal int Magic { get; set; }
|
internal int Magic { get; set; }
|
||||||
|
|
||||||
internal ManualResetEventSlim SchedulerReset { get; } = new(false);
|
|
||||||
|
|
||||||
private int Count { get; set; }
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetAllWorker()
|
public void SetAllWorker()
|
||||||
{
|
{
|
||||||
foreach (MatrixParallelThread t in _threads) {
|
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
|
||||||
t.Restart();
|
_threads[i].Restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,25 +78,124 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
{
|
{
|
||||||
while (tasks.TryDequeue(out nint handle))
|
while (tasks.TryDequeue(out nint handle))
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackageNonGeneric* task = (MatrixParallelTaskPackageNonGeneric*)handle;
|
MatrixParallelTaskPackage* task = (MatrixParallelTaskPackage*)handle;
|
||||||
PublishTaskToWorkers(task);
|
switch (task->ComputeMode.OperationStyle)
|
||||||
|
{
|
||||||
|
case MatrixOperationStyle.PANEL_OP:
|
||||||
|
break;
|
||||||
|
case MatrixOperationStyle.BUFFER_OP:
|
||||||
|
PublishBufferTaskToWorkers(task);
|
||||||
|
break;
|
||||||
|
case MatrixOperationStyle.KERNEL_OP:
|
||||||
|
PublishBufferTaskToWorkers(task);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void PublishTaskToWorkers(MatrixParallelTaskPackageNonGeneric* taskPackage)
|
internal void SetScheduler()
|
||||||
{
|
{
|
||||||
int primCount = taskPackage->PrimCount;
|
MatrixParallelThread thread = _threads[_begin];
|
||||||
int secCount = taskPackage->SecCount;
|
thread.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
int primAverage = primCount / Count;
|
private void PublishBufferTaskToWorkers(MatrixParallelTaskPackage* package)
|
||||||
int secAverage = secCount / Count;
|
{
|
||||||
bool shouldSliceSec = secAverage > 512;
|
long count = Unsafe.As<int, long>(ref package->PrimCount);
|
||||||
for (int i = _begin; i < _begin + Count; i++)
|
long recommendCount = count / 1024;
|
||||||
|
MatrixParallelThread[] pool = _threads;
|
||||||
|
if (pool.Length == 1)
|
||||||
{
|
{
|
||||||
Queue<IntPtr> tasks = _threads[i].Tasks;
|
pool[0].Tasks.Enqueue((nint)package);
|
||||||
MatrixParallelTaskPackageNonGeneric* subTask = MatrixParallelFactory.FromExistPackage(taskPackage);
|
return;
|
||||||
subTask->PrimTileOffset = i * primAverage;
|
|
||||||
}
|
}
|
||||||
|
long actual = count / pool.Length;
|
||||||
|
long extra = count % pool.Length;
|
||||||
|
|
||||||
|
long offset = 0;
|
||||||
|
MatrixParallelTaskPackage* current = package;
|
||||||
|
foreach (MatrixParallelThread thread in pool)
|
||||||
|
{
|
||||||
|
long wrapTaskLength = actual;
|
||||||
|
long ex = extra > 0 ? 1 : 0;
|
||||||
|
extra -= ex;
|
||||||
|
ref long offsetRef = ref Unsafe.As<int, long>(ref current->PrimTileOffset);
|
||||||
|
offsetRef += offset;
|
||||||
|
ref long lengthRef = ref Unsafe.As<int, long>(ref current->PrimCount);
|
||||||
|
lengthRef = wrapTaskLength + ex;
|
||||||
|
pool[0].Tasks.Enqueue((nint)current);
|
||||||
|
current = MatrixParallelFactory.FromExistPackage(current);
|
||||||
|
offset += wrapTaskLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PublishKernelTaskToWorkers(MatrixParallelTaskPackage* package)
|
||||||
|
{
|
||||||
|
int primCount = package->PrimCount;
|
||||||
|
int secCount = package->SecCount;
|
||||||
|
MatrixParallelThread[] pool = _threads;
|
||||||
|
|
||||||
|
if (pool.Length == 1)
|
||||||
|
{
|
||||||
|
pool[0].Tasks.Enqueue((nint)package);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new NotImplementedException();
|
||||||
|
/*
|
||||||
|
int threadCount = pool.Length;
|
||||||
|
int tilePerThreadLess = tileCount / threadCount; // tiles per thread without extra slice
|
||||||
|
int columnAfterBaseTile = tileCount % threadCount * tileWidth; // tile sliced into columns
|
||||||
|
int extraColumnPerThread = columnAfterBaseTile / threadCount;
|
||||||
|
int extraColumnCount = columnAfterBaseTile % threadCount; // columns to be sliced
|
||||||
|
|
||||||
|
int total = primCount;
|
||||||
|
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
|
||||||
|
MatrixParallelTaskPackageNonGeneric* current = package;
|
||||||
|
foreach (MatrixParallelWrap wrap in pool.Wraps)
|
||||||
|
{
|
||||||
|
bool hasSlice = columnAfterBaseTile > 0;
|
||||||
|
bool isLargeSlice = extraColumnCount > 0;
|
||||||
|
|
||||||
|
// _count tiles for wrap
|
||||||
|
int wrapWidth = wrap!.WrapTaskCapacity;
|
||||||
|
int columnFromSlicingCount = (hasSlice ? extraColumnPerThread : 0) * wrapWidth;
|
||||||
|
int baseColumn = wrapWidth * tilePerThreadLess * tileWidth;
|
||||||
|
int columnInWrap = baseColumn + columnFromSlicingCount + (isLargeSlice ? 1 : 0);
|
||||||
|
|
||||||
|
// set tasks
|
||||||
|
if (columnInWrap == 0)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
throw new InvalidOperationException("Zero tasks published.");
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// update current task
|
||||||
|
current->PrimColumnCountInTile = columnInWrap;
|
||||||
|
current->SecColumnCountInTile = current->SecCount;
|
||||||
|
current->SecTileOffset = 0;
|
||||||
|
|
||||||
|
// remove tiles _count
|
||||||
|
extraColumnCount--;
|
||||||
|
columnAfterBaseTile -= columnFromSlicingCount;
|
||||||
|
total -= columnInWrap;
|
||||||
|
|
||||||
|
// set to wrap and push
|
||||||
|
wrap.WrapTask = current;
|
||||||
|
|
||||||
|
if (total <= 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = MatrixParallelFactory.FromExistPackage(current);
|
||||||
|
current->PrimTileOffset += columnInWrap;
|
||||||
|
}
|
||||||
|
/**/
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Handle(int inWrapIndex, MatrixParallelWrap wrap)
|
public class Handle(int inWrapIndex, MatrixParallelWrap wrap)
|
||||||
@@ -121,15 +219,11 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
#region wrap task
|
#region wrap task
|
||||||
|
|
||||||
internal MatrixParallelTaskPackageNonGeneric* WrapTask { get; set; }
|
internal unsafe Queue<nint> WrapTask { get; set; } = [];
|
||||||
|
|
||||||
internal int WrapTaskSliceCount { get; set; }
|
internal int WrapTaskSliceCount { get; set; }
|
||||||
|
|
||||||
internal int WrapTaskCapacity
|
internal int WrapTaskCapacity { get ; init; }
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => _threads.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
|
|
||||||
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
||||||
|
|
||||||
private static SlabAllocator<MatrixParallelTaskPackageNonGeneric> _wrapAllocator;
|
private static SlabAllocator<MatrixParallelTaskPackage> _wrapAllocator;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static MatrixParallelTaskPackage<T>* CreateBaseTask<T>() where T: unmanaged, INumber<T>
|
public static MatrixParallelTaskPackage* CreateBaseTask<T>() where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage<T>* p = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
|
||||||
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage<T>));
|
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage));
|
||||||
s.Fill(0);
|
s.Fill(0);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -74,20 +74,19 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static unsafe MatrixParallelTaskPackage<T>* FromExistPackage<T>(MatrixParallelTaskPackage<T>* exist)
|
public static unsafe MatrixParallelTaskPackage* FromExistPackage<T>(MatrixParallelTaskPackage* exist)
|
||||||
where T: unmanaged, INumber<T>
|
where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage<T>* ptr = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage* ptr = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
|
||||||
MatrixParallelTaskPackage<T>.Copy(exist, ptr);
|
MatrixParallelTaskPackage.Copy(exist, ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static unsafe MatrixParallelTaskPackageNonGeneric* FromExistPackage(
|
public static unsafe MatrixParallelTaskPackage* FromExistPackage(MatrixParallelTaskPackage* exist)
|
||||||
MatrixParallelTaskPackageNonGeneric* exist)
|
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackageNonGeneric* ptr = (MatrixParallelTaskPackageNonGeneric*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage* ptr = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
|
||||||
MatrixParallelTaskPackageNonGeneric.Copy(exist, ptr);
|
MatrixParallelTaskPackage.Copy(exist, ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Release(MatrixParallelTaskPackageNonGeneric* source)
|
public static void Release(MatrixParallelTaskPackage* source)
|
||||||
{
|
{
|
||||||
if (source->Scalar != null) {
|
if (source->Scalar != null) {
|
||||||
_scalarAllocator.Free((nuint)source->Scalar);
|
_scalarAllocator.Free((nuint)source->Scalar);
|
||||||
@@ -108,7 +107,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Release<T>(MatrixParallelTaskPackage<T>* source) where T: unmanaged, INumber<T>
|
public static void Release<T>(MatrixParallelTaskPackage* source) where T : unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
if (source->Scalar != null) {
|
if (source->Scalar != null) {
|
||||||
_scalarAllocator.Free((nuint)source->Scalar);
|
_scalarAllocator.Free((nuint)source->Scalar);
|
||||||
@@ -123,7 +122,7 @@ namespace StgSharp.Mathematics.Numeric
|
|||||||
{
|
{
|
||||||
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
|
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
|
||||||
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
|
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
|
||||||
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackageNonGeneric>.
|
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackage>.
|
||||||
Create(128 * 1024, SlabBufferLayout.Chunked);
|
Create(128 * 1024, SlabBufferLayout.Chunked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-116
@@ -62,133 +62,20 @@ namespace StgSharp
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
World.Initialize().UseModule<NumericalModule>().UseModule<GraphicModule>().InitializeModule();
|
World.Initialize().UseModule<NumericalModule>().UseModule<GraphicModule>().InitializeModule();
|
||||||
TestRender();
|
|
||||||
/*
|
|
||||||
// New test with synchronized start:
|
|
||||||
// - 8 producer threads, each pushing 1000 unique integers
|
|
||||||
// - 8 consumer threads, each attempting to pop 1000 times
|
|
||||||
// - Consumers print one line per successful pop
|
|
||||||
// - Finally, print popped/remaining counts and values
|
|
||||||
|
|
||||||
const int producerThreads = 8;
|
// TestRender();
|
||||||
const int consumerThreads = 8;
|
|
||||||
const int perProducer = 1000;
|
|
||||||
const int perConsumerAttempts = 1000;
|
|
||||||
|
|
||||||
ConcurrentBufferStack<int> stack = new ConcurrentBufferStack<int>();
|
|
||||||
Thread[] producers = new Thread[producerThreads];
|
|
||||||
Thread[] consumers = new Thread[consumerThreads];
|
|
||||||
ConcurrentBag<int> popped = new ConcurrentBag<int>();
|
|
||||||
|
|
||||||
int totalThreads = producerThreads + consumerThreads;
|
|
||||||
using CountdownEvent ready = new CountdownEvent(totalThreads);
|
|
||||||
using ManualResetEventSlim startGate = new ManualResetEventSlim(false);
|
|
||||||
|
|
||||||
for (int c = 0; c < consumerThreads; c++)
|
|
||||||
{
|
|
||||||
consumers[c] = new Thread(() => {
|
|
||||||
ready.Signal();
|
|
||||||
startGate.Wait();
|
|
||||||
|
|
||||||
for (int k = 0; k < perConsumerAttempts; k++)
|
|
||||||
{
|
|
||||||
if (stack.TryPop(out int v))
|
|
||||||
{
|
|
||||||
popped.Add(v);
|
|
||||||
|
|
||||||
// Console.WriteLine($"pop: {v}");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
Thread.Yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
{
|
|
||||||
IsBackground = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int p = 0; p < producerThreads; p++)
|
|
||||||
{
|
|
||||||
int captured = p;
|
|
||||||
producers[p] = new Thread(() => {
|
|
||||||
ready.Signal();
|
|
||||||
startGate.Wait();
|
|
||||||
|
|
||||||
int begin = captured * perProducer + 10 * perProducer;
|
|
||||||
for (int j = 0; j < perProducer; j++)
|
|
||||||
{
|
|
||||||
stack.Push(begin + j);
|
|
||||||
if ((j & 0xFF) == 0) {
|
|
||||||
Thread.Yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
{
|
|
||||||
IsBackground = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Thread t in consumers) {
|
|
||||||
t.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Thread t in producers) {
|
|
||||||
t.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all threads are ready, then start simultaneously
|
|
||||||
ready.Wait();
|
|
||||||
startGate.Set();
|
|
||||||
|
|
||||||
foreach (Thread t in producers) {
|
|
||||||
t.Join();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Thread t in consumers) {
|
|
||||||
t.Join();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gather remaining data
|
|
||||||
List<int> remaining = [];
|
|
||||||
while (stack.TryPop(out int value)) {
|
|
||||||
remaining.Add(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($"Popped count: {popped.Count}");
|
|
||||||
/*
|
|
||||||
Console.WriteLine("Popped values:");
|
|
||||||
foreach (int v in popped)
|
|
||||||
{
|
|
||||||
Console.Write(v);
|
|
||||||
Console.Write('\t');
|
|
||||||
}
|
|
||||||
Console.WriteLine();
|
|
||||||
/*
|
|
||||||
Console.WriteLine($"Remaining count: {remaining.Count}");
|
|
||||||
Console.WriteLine("Remaining values:");
|
|
||||||
foreach (int v in remaining)
|
|
||||||
{
|
|
||||||
Console.Write(v);
|
|
||||||
Console.Write('\t');
|
|
||||||
}
|
|
||||||
Console.WriteLine();
|
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
Console.WriteLine($"Produced: {producerThreads * perProducer}, Popped+Remaining: {popped.Count + remaining.Count}");
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// 原有的矩阵测试代码
|
// 原有的矩阵测试代码
|
||||||
HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400);
|
HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400);
|
||||||
|
|
||||||
Matrix<float> m = Matrix<float>.FromHlsf(20, 20, hlsf);
|
Matrix<float> m = Matrix<float>.FromHlsf(200, 200, hlsf);
|
||||||
m.Fill(1.0f);
|
m.Fill(1.0f);
|
||||||
Matrix<float> n = m.Add(m);
|
Matrix<float> n = m.Add(m);
|
||||||
for (int i = 0; i < 20; i++)
|
for (int i = 0; i < 20; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 20; j++) {
|
for (int j = 0; j < 20; j++) {
|
||||||
Console.Write($"{n[i, j].ToString("0.000")}\t");
|
Console.Write($"{n[i, j]:0.0E+00} \t");
|
||||||
}
|
}
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
@@ -198,6 +85,7 @@ namespace StgSharp
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex);
|
Console.WriteLine(ex);
|
||||||
|
Console.ReadLine();
|
||||||
/*
|
/*
|
||||||
World.WriteLog($"{ex}", LogType.Error);
|
World.WriteLog($"{ex}", LogType.Error);
|
||||||
if( true ) { }
|
if( true ) { }
|
||||||
|
|||||||
Reference in New Issue
Block a user