From b71515b2d421cafe691a64016ac7735374b8f34e Mon Sep 17 00:00:00 2001 From: Nitload Date: Wed, 25 Feb 2026 00:20:09 +0800 Subject: [PATCH] per thread context loading is ok, working on global context --- .cr/team/Editor/Formatting/Spaces.CSharp.xml | 32 ++++++ StgSharp.Common/Environment/Platform.cs | 85 ++++++-------- .../Intrinsic/intrinsicContextProvider.cs | 52 ++++----- .../Numeric/MatrixParallel.cs | 44 +++++++- .../Numeric/MatrixParallelThread.cs | 105 ++++++------------ .../Numeric/MatrixParallelWrap.cs | 71 ++++++------ StgSharp.Native/sn-head/StgSharpNative.h | 2 +- StgSharp.Native/sn-src/load_intrinsic.x86.c | 3 +- StgSharp.Native/sn-src/simdid_compare.x86.c | 49 ++++---- 9 files changed, 225 insertions(+), 218 deletions(-) create mode 100644 .cr/team/Editor/Formatting/Spaces.CSharp.xml diff --git a/.cr/team/Editor/Formatting/Spaces.CSharp.xml b/.cr/team/Editor/Formatting/Spaces.CSharp.xml new file mode 100644 index 00000000..961a706f --- /dev/null +++ b/.cr/team/Editor/Formatting/Spaces.CSharp.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + \ No newline at end of file diff --git a/StgSharp.Common/Environment/Platform.cs b/StgSharp.Common/Environment/Platform.cs index 529f09c7..2a8e1824 100644 --- a/StgSharp.Common/Environment/Platform.cs +++ b/StgSharp.Common/Environment/Platform.cs @@ -1,27 +1,30 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="Platform" +// file="Platform.cs" // Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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. +// 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. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -84,41 +87,31 @@ namespace StgSharp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogError( - Exception ex - ) + public static void LogError(Exception ex) { DefaultLog.InternalWriteLog(ex.Message, LogType.Error); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogInfo( - string log - ) + public static void LogInfo(string log) { DefaultLog.InternalWriteLog(log, LogType.Info); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogWarning( - string log - ) + public static void LogWarning(string log) { DefaultLog.InternalWriteLog(log, LogType.Warning); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogWarning( - Exception notVerySeriesException - ) + public static void LogWarning(Exception notVerySeriesException) { DefaultLog.InternalWriteLog(notVerySeriesException.Message, LogType.Warning); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Mark( - bool needConsole - ) + public static void Mark(bool needConsole) { markCount++; if (needConsole) { @@ -126,9 +119,7 @@ namespace StgSharp } } - public static void Terminate( - int exitCode - ) + public static void Terminate(int exitCode) { MainTimeProvider.StopProvidingTime(); GraphicFramework.glfwTerminate(); @@ -141,8 +132,7 @@ namespace StgSharp bool isConsole, [CallerFilePath] string filePath = "", [CallerMemberName] string callerName = "", - [CallerLineNumber] int lineNumber = 0 - ) + [CallerLineNumber] int lineNumber = 0) { Type t = target.GetType(); string log = $"Tracked object: {nameof(target)}\t\tType:{t.Name}\n"; @@ -173,17 +163,12 @@ namespace StgSharp /// The severity of current message. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteLog( - string message, - LogType logType - ) + public static void WriteLog(string message, LogType logType) { DefaultLog.InternalWriteLog(message, logType); } - internal static TDele ConvertAPI( - IntPtr funcPtr - ) + internal static TDele ConvertAPI(IntPtr funcPtr) { if (funcPtr == IntPtr.Zero) { throw new InvalidCastException( @@ -199,10 +184,7 @@ namespace StgSharp } } - internal static Delegate ConvertAPI( - IntPtr funcPtr, - Type T - ) + internal static Delegate ConvertAPI(IntPtr funcPtr, Type T) { if (funcPtr == IntPtr.Zero) { throw new InvalidCastException( @@ -238,7 +220,6 @@ namespace StgSharp Dialogue.CreateDialogueProcessIfNotExist(); } /**/ - NativeIntrinsic.InitIntrinsicContext(); } internal class Initializer : IStaticModule diff --git a/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs b/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs index 981cfbaa..55effeee 100644 --- a/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs +++ b/StgSharp.Common/Internal/Intrinsic/intrinsicContextProvider.cs @@ -1,27 +1,30 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="intrinsicContextProvider" +// file="intrinsicContextProvider.cs" // Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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. +// 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. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -47,6 +50,7 @@ namespace StgSharp.Internal get => _intrinsicContext; } + /* internal static void InitIntrinsicContext() { ulong statCode = 0; @@ -71,10 +75,8 @@ namespace StgSharp.Internal } [LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")] - [UnmanagedCallConv(CallConvs =[ typeof(CallConvCdecl) ])] - private static partial ulong LoadIntrinsicFunction( - IntrinsicContext* context - ); - + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static partial void LoadIntrinsicFunction(IntrinsicContext* context, ulong id); + /**/ } } \ No newline at end of file diff --git a/StgSharp.Mathematics/Numeric/MatrixParallel.cs b/StgSharp.Mathematics/Numeric/MatrixParallel.cs index a46476ac..c4acd29f 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallel.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallel.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixParallel" // Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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 @@ -27,10 +27,14 @@ // ----------------------------------------------------------------------- using StgSharp.Collections; using StgSharp.HighPerformance.Memory; +using StgSharp.Internal; using StgSharp.Internal.Intrinsic; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -43,6 +47,8 @@ namespace StgSharp.Mathematics.Numeric private static CapacityFixedStack _threads; + private static ConcurrentDictionary contextMap; + private static SlabAllocator contextAllocator; public static bool IsParallelSupported { get; } = Environment.ProcessorCount > 6; @@ -51,6 +57,22 @@ namespace StgSharp.Mathematics.Numeric 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; + } + } + internal static void Init() { if (IsInitialized) { @@ -63,16 +85,32 @@ namespace StgSharp.Mathematics.Numeric } MatrixParallelFactory.Init(); contextAllocator = SlabAllocator.Create(4, SlabBufferLayout.Chunked, false); - int count = Environment.ProcessorCount - 4; + contextMap = []; + int count = Environment.ProcessorCount; _threads = new(count); for (int i = 0; i < count; i++) { MatrixParallelThread thread = new MatrixParallelThread(i); _threads.Push(thread); } + if (contextMap.Keys.Count == 1) + { + for (int i = 0; i < 4; i++) + { + MatrixParallelThread thread = _threads.Pop(); + thread.Dispose(); + } + } else + { + // TODO 排序并丢弃四个能力最弱线程 + } _awaitingLeaderHandle = new AwaitingQueue(); IsInitialized = true; } + [LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe partial void LoadIntrinsicFunction(IntrinsicContext* context, ulong id); + } } diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs b/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs index 90c0e10e..6ef881ec 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelThread.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixParallelThread" // Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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 @@ -27,18 +27,20 @@ // ----------------------------------------------------------------------- using StgSharp.Internal; using StgSharp.Internal.Intrinsic; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace StgSharp.Mathematics.Numeric { + internal enum MatrixThreadState : int + { + + Ready = 0, + Running = 1, + Idle = 2, + + } + public unsafe partial class MatrixParallelThread : IDisposable { @@ -47,9 +49,7 @@ namespace StgSharp.Mathematics.Numeric private readonly ManualResetEventSlim _resetEvent; private readonly Thread _managedThread; - internal MatrixParallelThread( - int poolId - ) + internal MatrixParallelThread(int poolId) { _resetEvent = new ManualResetEventSlim(false); _managedThread = new Thread(MatrixParallelWorkLoad); @@ -65,9 +65,11 @@ namespace StgSharp.Mathematics.Numeric internal IntrinsicContext* Intrinsic { get; set; } + internal bool IsSingle { get; set; } + internal MatrixParallelWrap BindedWrap { get; set; } - internal RoleType Role { get; set; } + internal MatrixThreadState state { get; set; } internal SIMDID Simd { get; set; } @@ -78,9 +80,7 @@ namespace StgSharp.Mathematics.Numeric } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void ExecuteTaskPackage( - MatrixParallelQueue taskQueue - ) + public static unsafe void ExecuteTaskPackage(MatrixParallelQueue taskQueue) { MatrixParallelTaskPackage* p = taskQueue.Package; switch (p->ComputeMode.OperationStyle) @@ -118,42 +118,22 @@ namespace StgSharp.Mathematics.Numeric [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Restart() { - if (Role == RoleType.Leader) - { - LeaderEvent?.Set(); - } else - { - _resetEvent.Set(); - } + _resetEvent.Set(); } - internal void MatrixParallelLeader() - { - Thread current = Thread.CurrentThread; - current.Priority = ThreadPriority.Highest; - LeaderEvent?.Wait(); - LeaderEvent?.Reset(); - - // Console.WriteLine("Leader is computing"); - BindedWrap.ReportThreadAccomplished(); - - // Console.WriteLine("leader's computing is done"); - Role = RoleType.Worker; - LeaderEvent = null; - current.Priority = BindedWrap.AfterWork; - } + [DllImport( + dllName: Native.LibName, + EntryPoint = "sn_get_simd_level_local", + CallingConvention = CallingConvention.Cdecl)] + internal static extern ulong GetSimdId(); [DllImport( dllName:Native.LibName, EntryPoint = "sn_set_thread_affinity", CallingConvention = CallingConvention.Cdecl)] - internal static extern void SetThreadAffinity( - int coreId - ); + internal static extern void SetThreadAffinity(int coreId); - protected virtual void Dispose( - bool disposing - ) + protected virtual void Dispose(bool disposing) { if (!disposedValue) { @@ -162,7 +142,6 @@ namespace StgSharp.Mathematics.Numeric _resetEvent.Dispose(); _managedThread.Join(); } - disposedValue = true; } } @@ -171,8 +150,10 @@ namespace StgSharp.Mathematics.Numeric { // Bind OS-thread affinity once when the worker starts running SetThreadAffinity(PoolId); - Thread.Sleep(0); - + Thread.Sleep(1); + SIMDID feature = new(); + feature.Mask = GetSimdId(); + _context = (nint*)MatrixParallel.GetContext(feature); while (true) { // Thread self = Thread.CurrentThread; @@ -180,35 +161,17 @@ namespace StgSharp.Mathematics.Numeric _resetEvent.Reset(); AfterWork = BindedWrap.AfterWork; _managedThread.Priority = ThreadPriority.Highest; - switch (Role) + if (IsSingle) { - case RoleType.Worker://worker - // _ = Interlocked.Decrement(ref RemainThreadCount); - // Console.WriteLine($"worker {Environment.CurrentManagedThreadId} start"); - ExecuteTaskPackage(BindedWrap.TaskQueue); - BindedWrap.ReportThreadAccomplished(); - - // Console.WriteLine($"worker {Environment.CurrentManagedThreadId} end"); - break; - case RoleType.SingleExternal: - - // TODO 将外部线程绑定到当前线程上,并执行任务包 - break; - default: - break; + // TODO 将外部线程绑定到当前线程上,并执行任务包 + } else + { + ExecuteTaskPackage(BindedWrap.TaskQueue); + BindedWrap.ReportThreadAccomplished(); } _managedThread.Priority = AfterWork; } } - internal enum RoleType : int - { - - Worker = 0, - Leader = 1, - SingleExternal = 2, - - } - } } diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs index b7acb535..8253b837 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelWrap.cs @@ -1,27 +1,30 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="MatrixParallelWrap" +// file="MatrixParallelWrap.cs" // Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. 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. +// 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. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -52,12 +55,8 @@ namespace StgSharp.Mathematics.Numeric private MatrixParallelThread[] _threads; private bool _disposed = false; private int _count; - private ManualResetEventSlim _leaderEvent = new ManualResetEventSlim(false); - public ThreadPriority AfterWork { get; private set; } - internal MatrixParallelWrap( - MatrixParallelThread[] threadArray - ) + internal MatrixParallelWrap(MatrixParallelThread[] threadArray) { _threads = threadArray; IsMultithread = threadArray.Length > 1; @@ -77,6 +76,8 @@ namespace StgSharp.Mathematics.Numeric } } + public ThreadPriority AfterWork { get; private set; } + private bool IsMultithread { get; init; } public void Dispose() @@ -89,22 +90,14 @@ namespace StgSharp.Mathematics.Numeric } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public MatrixParallelThread GetLeader() - { - MatrixParallelThread leader = Threads[1]; - leader.Role = MatrixParallelThread.RoleType.Leader; - leader.LeaderEvent = _leaderEvent; - return leader; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void LaunchParallel( - SleepMode afterWork - ) + public void LaunchParallel(SleepMode afterWork) { AfterWork = (ThreadPriority)afterWork; - MatrixParallelThread leader = GetLeader(); - leader.MatrixParallelLeader(); + foreach (MatrixParallelThread thread in _threads) + { + thread.AfterWork = AfterWork; + thread.BindedWrap = this; + } WaitAllWraps(); } diff --git a/StgSharp.Native/sn-head/StgSharpNative.h b/StgSharp.Native/sn-head/StgSharpNative.h index f4e64187..d936e11c 100644 --- a/StgSharp.Native/sn-head/StgSharpNative.h +++ b/StgSharp.Native/sn-head/StgSharpNative.h @@ -65,7 +65,7 @@ SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName); SN_API void SN_DECL unloadImageData(Image *out); SN_API char *SN_DECL readLog(void); SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table); -SN_API SIMDID SN_DECL load_intrinsic_function(void *intrinsic_context, uint64_t id); +SN_API void SN_DECL load_intrinsic_function(void *intrinsic_context, uint64_t id); SN_API SIMDID SN_DECL sn_get_simd_level_global(); /* Per-core variant: always re-executes CPUID, never caches. * Must be called on the target core (after affinity is set). */ diff --git a/StgSharp.Native/sn-src/load_intrinsic.x86.c b/StgSharp.Native/sn-src/load_intrinsic.x86.c index 0ca2f3a3..075e9653 100644 --- a/StgSharp.Native/sn-src/load_intrinsic.x86.c +++ b/StgSharp.Native/sn-src/load_intrinsic.x86.c @@ -19,7 +19,7 @@ PRIVATE void load_intrinsic_avx(sn_intrinsic *context, SIMDID id); PRIVATE void load_intrinsic_512_dual(sn_intrinsic *context, SIMDID id); PRIVATE void load_intrinsic_512(sn_intrinsic *context, SIMDID id); -SN_API SIMDID load_intrinsic_function(void *intrinsic_context, uint64_t id) +SN_API void load_intrinsic_function(void *intrinsic_context, uint64_t id) { sn_null_assert(intrinsic_context); @@ -45,7 +45,6 @@ SN_API SIMDID load_intrinsic_function(void *intrinsic_context, uint64_t id) load_intrinsic_512(context, simdid); break; } - return simdid; } void load_intrinsic_sse(sn_intrinsic *context, SIMDID id) diff --git a/StgSharp.Native/sn-src/simdid_compare.x86.c b/StgSharp.Native/sn-src/simdid_compare.x86.c index 72849620..0f3608c2 100644 --- a/StgSharp.Native/sn-src/simdid_compare.x86.c +++ b/StgSharp.Native/sn-src/simdid_compare.x86.c @@ -20,33 +20,34 @@ * [63..56] uArchHi make_byte[7] * ----------------------------------------------------------------------- */ -#define FIELD_MAIN(id) ((unsigned char)(id).make_byte[1]) -#define FIELD_AVX512(id) ((uint16_t)((unsigned char)(id).make_byte[2] | \ - ((unsigned char)(id).make_byte[3] << 8))) -#define FIELD_AMX(id) ((unsigned char)(id).make_byte[4]) -#define FIELD_AVX(id) ((unsigned char)(id).make_byte[5]) -#define FIELD_AVX10(id) ((unsigned char)(id).make_byte[6]) -#define FIELD_UARCH(id) ((unsigned char)(id).make_byte[7]) +#define FIELD_MAIN(id) ((unsigned char)(id).make_byte[1]) +#define FIELD_AVX512(id) \ + ((uint16_t)((unsigned char)(id).make_byte[2] | ((unsigned char)(id).make_byte[3] << 8))) +#define FIELD_AMX(id) ((unsigned char)(id).make_byte[4]) +#define FIELD_AVX(id) ((unsigned char)(id).make_byte[5]) +#define FIELD_AVX10(id) ((unsigned char)(id).make_byte[6]) +#define FIELD_UARCH(id) ((unsigned char)(id).make_byte[7]) /* Portable popcount for a 16-bit value. */ static int popcount16(uint16_t v) { int c = 0; - while (v) { v &= v - 1; c++; } + while (v) { + v &= v - 1; + c++; + } return c; } /* Map AVX512_IMPL 2-bit field to a strength ordinal for tie-breaking. - * DUAL(1) => 0 (weakest), UNKNOWN(0) => 1, NATIVE(2) => 2 (strongest) */ + * Index = impl value (0=UNKNOWN, 1=DUAL, 2=NATIVE, 3=reserved). + * Strength: DUAL(0) < UNKNOWN(1) < NATIVE(2). */ +static const int impl_strength_table[4] = { 1, 0, 2, 1 }; + static int impl_strength(uint16_t avx512) { unsigned impl = (avx512 >> SIMDID_AVX512_IMPL_SHIFT) & 0x3u; - switch (impl) { - case 1: return 0; /* DUAL — glue / downclock risk */ - case 0: return 1; /* UNKNOWN — conservatively mid */ - case 2: return 2; /* NATIVE — full-width ALU */ - default: return 1; /* reserved, treat as unknown */ - } + return impl_strength_table[impl]; } /* ----------------------------------------------------------------------- @@ -85,11 +86,10 @@ SN_API SIMDID SN_DECL sn_get_unite_simd(SIMDID left, SIMDID right) /* Clear the IMPL field, then set the weaker one */ int ls = impl_strength(l512); int rs = impl_strength(r512); - unsigned weak_impl = (ls <= rs) - ? ((l512 >> SIMDID_AVX512_IMPL_SHIFT) & 0x3u) - : ((r512 >> SIMDID_AVX512_IMPL_SHIFT) & 0x3u); - merged = (merged & ~(uint16_t)SIMDID_AVX512_IMPL_MASK) - | (uint16_t)(weak_impl << SIMDID_AVX512_IMPL_SHIFT); + int s = (ls <= rs) ? l512 : r512; /* pick the one with weaker strength ordinal */ + unsigned weak_impl = (s >> SIMDID_AVX512_IMPL_SHIFT) & 0x3u; + merged &= ~(uint16_t)SIMDID_AVX512_IMPL_MASK; + merged |= (uint16_t)(weak_impl << SIMDID_AVX512_IMPL_SHIFT); out.make_byte[2] = (char)(merged & 0xFF); out.make_byte[3] = (char)((merged >> 8) & 0xFF); @@ -171,10 +171,9 @@ SN_API int SN_DECL sn_compare_simd(SIMDID left, SIMDID right) if (lb != rb) return lb > rb ? 1 : -1; - /* 4. Extension popcount (mask out BASE + IMPL + reserved low nibble) */ - uint16_t ext_mask = (uint16_t)~(SIMDID_AVX512_BASE - | SIMDID_AVX512_IMPL_MASK - | 0x000Fu); + // 4. Extension popcount (mask out BASE + IMPL + reserved low nibble) + int drop = ~(SIMDID_AVX512_BASE | SIMDID_AVX512_IMPL_MASK | 0x000Fu); + uint16_t ext_mask = drop & (l512 | r512); /* only consider bits set in either */ int lp = popcount16(l512 & ext_mask); int rp = popcount16(r512 & ext_mask); if (lp != rp) @@ -196,4 +195,4 @@ SN_API int SN_DECL sn_compare_simd(SIMDID left, SIMDID right) return 0; } -#endif \ No newline at end of file +#endif