diff --git a/StgSharp.Mathematics/Internal/SIMDID.cs b/StgSharp.Mathematics/Internal/SIMDID.cs index 4b593e28..4421c961 100644 --- a/StgSharp.Mathematics/Internal/SIMDID.cs +++ b/StgSharp.Mathematics/Internal/SIMDID.cs @@ -42,6 +42,13 @@ namespace StgSharp.Mathematics.Internal [FieldOffset(0)]public fixed byte MaskByte[16]; [FieldOffset(0)]public ulong Mask; + internal SIMDID( + ulong data + ) + { + Mask = data; + } + public SIMDID() { Unsafe.SkipInit(out this); diff --git a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs index 7dc12e6e..f9078d74 100644 --- a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixCompute.Sequential" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -40,7 +40,11 @@ namespace StgSharp.Mathematics.Numeric.Linear public static unsafe partial class MatrixCompute { - public static void Add(Matrix left, Matrix right, Matrix ans) + public static void Add( + Matrix left, + Matrix right, + Matrix ans + ) { ArgumentNullException.ThrowIfNull(left, nameof(left)); ArgumentNullException.ThrowIfNull(right, nameof(right)); @@ -69,6 +73,7 @@ namespace StgSharp.Mathematics.Numeric.Linear t->Mat3 = (MatrixKernel*)ansPtr; t->ElementType = MatrixElementType.F64; t->Scalar.Data(0) = count; + MatrixParallelThread[] pool; if (count <= 256) { add(t); @@ -78,32 +83,44 @@ namespace StgSharp.Mathematics.Numeric.Linear return; } else if (count <= 1024) { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + pool = MatrixParallel.LeadParallel(1); add(t); MatrixParallel.ReturnParallelResources(ref pool); return; } - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask((nuint)add, t); + pool = MatrixParallel.LeadParallel((int)(count / 1024)); + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(pool, t); taskGroup.LaunchParallel(SleepMode.DeepSleep); taskGroup.Dispose(); return; } - private sealed class SequentialPredictor : MatrixPredictor + private struct SequentialPredictor : IMatrixPredictor { - public override bool Predict(Span node, out int count) + public bool Predict( + Span node, + out int count + ) { throw new NotImplementedException(); } - public override void Prefetch(nuint origin, ulong policy, Span cache) + public void Prefetch( + nuint origin, + ulong policy, + Span cache + ) { throw new NotImplementedException(); } - public override void WriteBack(nuint origin, ulong policy, ReadOnlySpan cache) + public void WriteBack( + nuint origin, + ulong policy, + ReadOnlySpan cache + ) { throw new NotImplementedException(); } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs index 577f186d..f3dbcc9b 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs @@ -41,23 +41,23 @@ namespace StgSharp.Mathematics.Numeric private static AwaitingQueue _awaitingLeaderHandle; - private static volatile int _createGeneration = 0; + private static volatile int _createGeneration; private static int _sortState; public static MatrixParallelThread[] LeadParallel( - int recommendCount + long recommendCount ) { - int min = int.Min(recommendCount, _threads.Capacity); + int recommend = (recommendCount > int.MaxValue) ? int.MaxValue : ((int)recommendCount); + int min = (int)long.Min(recommend, _threads.Capacity); min /= 2; MatrixParallelThread[] ret; if (_threads.Count < min) { - WaitHandle handle = new WaitHandle - ( + WaitHandle handle = new( _createGeneration, min, - recommendCount + recommend ); do { @@ -65,7 +65,7 @@ namespace StgSharp.Mathematics.Numeric { _awaitingLeaderHandle.Enqueue(handle); _ = Interlocked.Exchange(ref _sortState, 0); - Interlocked.Increment(ref _createGeneration); + _ = Interlocked.Increment(ref _createGeneration); break; } } while (true); @@ -100,7 +100,7 @@ namespace StgSharp.Mathematics.Numeric { if (Interlocked.Exchange(ref _sortState, 1) == 0) { - ret = _threads.PopRange(recommendCount); + ret = _threads.PopRange(recommend); _createGeneration++; _ = Interlocked.Exchange(ref _sortState, 0); return ret; @@ -120,7 +120,7 @@ namespace StgSharp.Mathematics.Numeric if (Interlocked.Exchange(ref _sortState, 1) == 0) { _threads.PushRange(pool); - Interlocked.Exchange(ref _sortState, 0); + _ = Interlocked.Exchange(ref _sortState, 0); break; } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs index 6e876e65..7a1c9d65 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixParallel.Publish" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -48,8 +48,10 @@ namespace StgSharp.Mathematics.Numeric [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe MatrixParallelWrap ScheduleTask(nuint computeHandle, MatrixParallelTask* package) - where TTask: IPrefetchPredict + internal static unsafe MatrixParallelWrap ScheduleTask( + MatrixParallelThread[] workers, + MatrixParallelTask* package + ) where TTask : IPrefetchPredict { /* int primCount = package->PrimCount; @@ -59,13 +61,10 @@ namespace StgSharp.Mathematics.Numeric // Console.WriteLine($"amount of kernels is {count}"); - long recommendCount = /*count / /**/ 1024; - MatrixParallelThread[] pool = LeadParallel((int)recommendCount); - MatrixParallelWrap wrap = new(pool) + return new(workers) { TaskQueue = MatrixParallelQueue.Rent(package) }; - return wrap; } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.cs index 66da4c22..e58f4566 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.cs @@ -49,36 +49,16 @@ namespace StgSharp.Mathematics.Numeric private static CapacityFixedStack _threads; - private static ConcurrentDictionary contextMap; - - private static SlabAllocator contextAllocator; - public static bool IsParallelSupported { get; } = Environment.ProcessorCount > 6; - public static bool IsParallelMeaningful => Environment.ProcessorCount > 6 && IsInitialized; + public static bool IsParallelMeaningful => (Environment.ProcessorCount > 6) && IsInitialized; - private static bool IsInitialized { get; set; } = false; - - internal static unsafe IntrinsicContext* GetContext( - SIMDID simd - ) - { - if (!IsParallelSupported) { - return null; - } - if (contextMap.TryGetValue(simd, out nint handle)) - { - return (IntrinsicContext*)handle; - } else - { - IntrinsicContext* context = (IntrinsicContext*)contextAllocator.Allocate(); - - return context; - } - } + private static bool IsInitialized { get; set; } internal static void Init() { + Dictionary contextMap = []; + if (IsInitialized) { return; } @@ -87,16 +67,15 @@ namespace StgSharp.Mathematics.Numeric IsInitialized = true; return; } - MatrixParallelFactory.Init(); - contextAllocator = SlabAllocator.Create(4, SlabBufferLayout.Chunked, false); contextMap = []; int count = Environment.ProcessorCount; _threads = new(count); for (int i = 0; i < count; i++) { - MatrixParallelThread thread = new MatrixParallelThread(i); + MatrixParallelThread thread = new(i); _threads.Push(thread); SpinWait.SpinUntil(() => thread.State == MatrixThreadState.Ready); + var index = (IsParallelSupported && contextMap.TryGetValue(simd, out int index)) ? index : (-1); } // TODO 构建全局的保底上下文 diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Concurrent.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Concurrent.cs deleted file mode 100644 index 98c05ebb..00000000 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Concurrent.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixParallelQueue.Concurrent" -// 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 System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric.Runtime -{ - internal unsafe class ConcurrentPointerQueue - { - - private nuint* _current; - private int[] _length; - private nuint[] _queue; - private int _bucketIndex; - private int _head; - private int _tail; - - public ConcurrentPointerQueue() - { - _queue = new nuint[8]; - } - - public void Enqueue( - nuint* pointer, - int count - ) - { - _head++; - _head %= _queue.Length; - _bucketIndex = 0; - _queue[_head] = (nuint)pointer; - _length[_head] = count; - } - - public int TryDequeue( - Span span - ) - { - throw new NotImplementedException(); - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs index 6b85d2ab..0575feb1 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs @@ -1,9 +1,9 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="MatrixPredictor" +// file="MatrixParallelQueue.Predictor" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -34,16 +34,6 @@ using System.Threading.Tasks; namespace StgSharp.Mathematics.Numeric.Runtime { - public abstract class MatrixPredictor : IPrefetchPredict where TSelf: MatrixPredictor - { - - protected MatrixPredictor() { } - - public abstract bool Predict(Span node, out int count); - - public abstract void Prefetch(nuint origin, ulong policy, Span cache); - - public abstract void WriteBack(nuint origin, ulong policy, ReadOnlySpan cache); - - } + internal interface IMatrixPredictor : IPrefetchPredict + where TSelf : unmanaged, IMatrixPredictor { } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs index 3be87f00..362c618c 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs @@ -50,13 +50,7 @@ namespace StgSharp.Mathematics.Numeric public MatrixParallelTask* BaseTask { get; private set; } - public MatrixElementType ElementType { get; private set; } - - public MatrixIntrinsicHandle Handle { get; private set; } - public static MatrixParallelQueue Rent( - MatrixElementType elementType, - MatrixIntrinsicHandle handle, MatrixParallelTask* pack ) { @@ -66,8 +60,6 @@ namespace StgSharp.Mathematics.Numeric queue.BaseTask = pack; queue._maxCount = ((ulong)pack->CommonX) * ((ulong)pack->CommonY); queue._cursor = 0; - queue.ElementType = elementType; - queue.Handle = handle; return queue; } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelTask.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelTask.cs index c2399895..782528e0 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelTask.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelTask.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixParallelTask" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -36,17 +36,18 @@ namespace StgSharp.Mathematics.Numeric.Runtime internal unsafe struct MatrixParallelTask { - [FieldOffset(0)] public MatrixKernel* Mat1; // 8 - [FieldOffset(8)] public MatrixKernel* Mat2; // 8 - [FieldOffset(16)] public MatrixKernel* Mat3; // 16 - [FieldOffset(40)] public int CommonK; - [FieldOffset(32)] public int CommonX; - [FieldOffset(36)] public int CommonY; - [FieldOffset(44)] public int i; - [FieldOffset(48)] public int j; - [FieldOffset(52)] public int k; - [FieldOffset(56)] public MatrixElementType ElementType; // 56 - [FieldOffset(24)] public nint Span; // 24 + [FieldOffset(0)] public MatrixKernel* Mat1; + [FieldOffset(8)] public MatrixKernel* Mat2; + [FieldOffset(16)] public MatrixKernel* Mat3; + [FieldOffset(24)] public int CacheIndex; + [FieldOffset(28)] public int CacheLength; + [FieldOffset(32)] public int CommonK; + [FieldOffset(36)] public int CommonX; + [FieldOffset(40)] public int CommonY; + [FieldOffset(44)] public int SpanLength; + [FieldOffset(48)] public MatrixElementType ElementType; + [FieldOffset(52)] public MatrixIntrinsicHandle ComputeHandle; + [FieldOffset(56)] public nint Span; [FieldOffset(64)] public ScalarPacket Scalar; public MatrixParallelTask() @@ -55,9 +56,13 @@ namespace StgSharp.Mathematics.Numeric.Runtime } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Copy(MatrixParallelTask* source, MatrixParallelTask* target) + public static void Copy( + MatrixParallelTask* source, + MatrixParallelTask* target + ) { - Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTask), sizeof(MatrixParallelTask)); + Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTask), + sizeof(MatrixParallelTask)); } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs index 7fbd968d..1839d1a7 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs @@ -69,10 +69,10 @@ namespace StgSharp.Mathematics.Numeric internal ManualResetEventSlim? LeaderEvent { get; set; } - internal IntrinsicContext* Intrinsic { get; set; } - internal bool IsSingle { get; set; } + internal IntrinsicContext Intrinsic { get; private set; } + internal MatrixParallelWrap BindedWrap { get; set; } internal MatrixThreadState State { get; set; } @@ -91,16 +91,6 @@ namespace StgSharp.Mathematics.Numeric _resetEvent.Set(); } - [LibraryImport(Native.LibName, EntryPoint = "sn_get_simd_level_local")] - [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - internal static partial ulong GetSimdId(); - - [LibraryImport(Native.LibName, EntryPoint = "sn_set_thread_affinity")] - [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - internal static partial void SetThreadAffinity( - int coreId - ); - protected virtual void Dispose( bool disposing ) @@ -125,11 +115,10 @@ namespace StgSharp.Mathematics.Numeric // Bind OS-thread affinity once when the worker starts running SetThreadAffinity(PoolId); _ = Thread.Yield(); - SIMDID feature = new() - { - Mask = GetSimdId() - }; - _context = (nint*)MatrixParallel.GetContext(feature); + SIMDID feature = new(GetSimdId()); + int index = MatrixParallel.GetContext(feature); + Intrinsic = new IntrinsicContext(); + if (index > 0) { } State = MatrixThreadState.Ready; while (true) { @@ -171,5 +160,19 @@ namespace StgSharp.Mathematics.Numeric State = MatrixThreadState.Retired; } +#pragma warning disable CA5393 + [LibraryImport(Native.LibName, EntryPoint = "sn_get_simd_level_local")] + [UnmanagedCallConv(CallConvs = [ typeof(CallConvCdecl) ])] + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)] + internal static partial ulong GetSimdId(); + + [LibraryImport(Native.LibName, EntryPoint = "sn_set_thread_affinity")] + [UnmanagedCallConv(CallConvs = [ typeof(CallConvCdecl) ])] + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)] + internal static partial void SetThreadAffinity( + int coreId + ); + +#pragma warning restore CA5393 } }