From 06e3aa119b6816483e5c5f749499ad6d20bd1136 Mon Sep 17 00:00:00 2001
From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com>
Date: Thu, 26 Mar 2026 18:02:13 +0800
Subject: [PATCH] mat
---
.../HighPerformance/Memory/L4.Predict.cs | 43 ++++++--
.../HighPerformance/Memory/L4.Prefetch.cs | 6 +-
StgSharp.Common/HighPerformance/Memory/L4.cs | 99 ++++++++++---------
StgSharp.Mathematics/Numeric/Linear/Matrix.cs | 30 +++---
.../Linear/MatrixCompute.Sequential.cs | 32 ++++--
.../Runtime/MatrixParallel.AwaitingQueue.cs | 2 +-
.../Numeric/Runtime/MatrixParallel.Publish.cs | 2 +-
.../Numeric/Runtime/MatrixParallel.Source.cs | 17 ----
.../Runtime/MatrixParallelQueue.Predictor.cs | 14 ++-
.../Numeric/Runtime/MatrixParallelQueue.cs | 9 +-
.../Numeric/Runtime/MatrixParallelThread.cs | 26 +++--
.../Numeric/Runtime/MatrixParallelWrap.cs | 21 ++--
StgSharp.Native/StgSharp.Native.vcxproj | 2 +-
.../StgSharp.Native.vcxproj.filters | 2 +-
.../{m.basic.x86.c => m.transpose.x86.c} | 0
StgSharp.Native/sn-src/simdid.x86.c | 21 +---
.../View/PresentorDescription.cs | 4 +-
StgSharpDebug/TestL4.cs | 4 +-
StgSharpDebug/TestL4Behaviour.cs | 17 ++--
StgSharpDebug/TestL4Prefetch.cs | 16 +--
20 files changed, 198 insertions(+), 169 deletions(-)
delete mode 100644 StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Source.cs
rename StgSharp.Native/sn-src/{m.basic.x86.c => m.transpose.x86.c} (100%)
diff --git a/StgSharp.Common/HighPerformance/Memory/L4.Predict.cs b/StgSharp.Common/HighPerformance/Memory/L4.Predict.cs
index 388f7fa3..7497b0f6 100644
--- a/StgSharp.Common/HighPerformance/Memory/L4.Predict.cs
+++ b/StgSharp.Common/HighPerformance/Memory/L4.Predict.cs
@@ -33,9 +33,11 @@ using System.Threading.Tasks;
namespace StgSharp.HighPerformance.Memory
{
- public interface IPrefetchPredict
+ public interface IL4Predict
{
+ bool IsExhausted { get; }
+
///
/// Writes predicted cache line descriptors into .
///
@@ -43,17 +45,20 @@ namespace StgSharp.HighPerformance.Memory
/// Prediction output buffer.
///
///
- /// When this method returns, contains the number of valid entries written to . The value must not exceed .Length.
///
///
/// if any prediction data was produced; otherwise, .
///
- bool Predict(Span node, out int count);
+ bool Predict(
+ Span node,
+ out int count
+ );
///
- /// Materializes the cache line identified by into into .
///
///
@@ -65,7 +70,11 @@ namespace StgSharp.HighPerformance.Memory
///
/// Destination cache line buffer.
///
- void Prefetch(nuint origin, ulong policy, Span cache);
+ void Prefetch(
+ nuint origin,
+ ulong policy,
+ Span cache
+ );
///
/// Writes the cache line in back to .
@@ -79,21 +88,29 @@ namespace StgSharp.HighPerformance.Memory
///
/// Source cache line buffer.
///
- void WriteBack(nuint origin, ulong policy, ReadOnlySpan cache);
+ void WriteBack(
+ nuint origin,
+ ulong policy,
+ ReadOnlySpan cache
+ );
}
public struct CacheLinePrediction : IEquatable
{
- public override readonly bool Equals(object? obj)
+ public override readonly bool Equals(
+ object? obj
+ )
{
return obj is CacheLinePrediction prediction &&
Address.Equals(prediction.Address) &&
MapPolicy == prediction.MapPolicy;
}
- public readonly bool Equals(CacheLinePrediction other)
+ public readonly bool Equals(
+ CacheLinePrediction other
+ )
{
return
Address == other.Address && MapPolicy == other.MapPolicy;
@@ -104,11 +121,17 @@ namespace StgSharp.HighPerformance.Memory
return HashCode.Combine(Address, MapPolicy);
}
- public static bool operator !=(CacheLinePrediction left, CacheLinePrediction right)
+ public static bool operator !=(
+ CacheLinePrediction left,
+ CacheLinePrediction right
+ )
{
return !(left == right);
}
- public static bool operator ==(CacheLinePrediction left, CacheLinePrediction right)
+ public static bool operator ==(
+ CacheLinePrediction left,
+ CacheLinePrediction right
+ )
{
return left.Equals(right);
}
diff --git a/StgSharp.Common/HighPerformance/Memory/L4.Prefetch.cs b/StgSharp.Common/HighPerformance/Memory/L4.Prefetch.cs
index 540d5a48..52204682 100644
--- a/StgSharp.Common/HighPerformance/Memory/L4.Prefetch.cs
+++ b/StgSharp.Common/HighPerformance/Memory/L4.Prefetch.cs
@@ -43,7 +43,9 @@ namespace StgSharp.HighPerformance.Memory
throw new OverflowException("Too many activated cache line in external reference.");
}
Span span = new(_prediction, PredictionCount);
- if (!(PrefetchPredict.Predict(span, out int actualCount) && actualCount > 0)) {
+ if (!PrefetchPredict.Predict(span, out int actualCount) && (actualCount <= 0))
+ {
+ _exhausted = true;
return;
}
int missIndex = 0;
@@ -85,7 +87,7 @@ namespace StgSharp.HighPerformance.Memory
head->_origin = address;
head->_profile = handle.MapPolicy;
head->_refCount = 0;
- head->_address = (nuint)(&_data[index]);
+ head->_address = nuint & _data[index];
// pre fetch them here
PrefetchPredict.Prefetch(head->_origin, head->_profile, new Span((byte*)head->_address, Unsafe.SizeOf()));
diff --git a/StgSharp.Common/HighPerformance/Memory/L4.cs b/StgSharp.Common/HighPerformance/Memory/L4.cs
index 734e113f..92bbd0b8 100644
--- a/StgSharp.Common/HighPerformance/Memory/L4.cs
+++ b/StgSharp.Common/HighPerformance/Memory/L4.cs
@@ -39,7 +39,6 @@ namespace StgSharp.HighPerformance.Memory
private const int PredictionLeastAhead = 1024;
private readonly CacheLineData* _data;
-
private readonly EvictionArray* _eviction;
private readonly CacheLineHead* _head;
private readonly CacheLinePrediction* _prediction;
@@ -57,12 +56,12 @@ namespace StgSharp.HighPerformance.Memory
public L4()
{
// init order is fallow by align requirement of each component.
- nuint cacheSize = (nuint)Unsafe.SizeOf() * CacheLineCount; // SIMDID, no less than 16 byte bit
- nuint entrySize = (nuint)Unsafe.SizeOf() * CacheLineCount; // 16 byte align
- nuint predictionSize = (nuint)Unsafe.SizeOf() * PredictionCount; //16 byte align
+ nuint cacheSize = ((nuint)Unsafe.SizeOf()) * CacheLineCount; // SIMDID, no less than 16 byte bit
+ nuint entrySize = ((nuint)Unsafe.SizeOf()) * CacheLineCount; // 16 byte align
+ nuint predictionSize = ((nuint)Unsafe.SizeOf()) * PredictionCount; //16 byte align
nuint mapSize = (nuint)SwissTable.RequestedNativeMemorySize; // 16 byte align
nuint rrpvSize = (nuint)Unsafe.SizeOf(); // 16 byte align
- nuint stackSize = (nuint)sizeof(int) * CacheLineCount; // int align
+ nuint stackSize = ((nuint)sizeof(int)) * CacheLineCount; // int align
// malloc all memory at once, and free at once in Dispose.
// This is to avoid fragmentation and improve performance.
@@ -85,7 +84,17 @@ namespace StgSharp.HighPerformance.Memory
ptr += stackSize;
}
- public IPrefetchPredict PrefetchPredict { get; set; }
+ public IL4Predict PrefetchPredict { get; set; }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ContinueOnce(
+ L4CacheLine line
+ )
+ {
+ if (line.Address > 0) {
+ _ = Interlocked.Decrement(ref _aheadCount);
+ }
+ }
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Design",
@@ -108,11 +117,11 @@ namespace StgSharp.HighPerformance.Memory
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public CacheLine Map(
- nuint origin
+ public L4CacheLine Map(
+ nuint origin
)
{
- if (_aheadCount < PredictionLeastAhead)
+ if ((_aheadCount < PredictionLeastAhead) && !PrefetchPredict.IsExhausted)
{
if (Interlocked.CompareExchange(ref _prefetching, 1, 0) == 0)
{
@@ -141,7 +150,7 @@ namespace StgSharp.HighPerformance.Memory
(*_eviction)[entry->_id] = 0;
_ = Interlocked.Increment(ref _activeCount);
_ = Interlocked.Decrement(ref _aheadCount);
- return new CacheLine(entry->_address, ref _activeCount, ref entry->_refCount);
+ return new L4CacheLine(entry->_address, ref _activeCount, ref entry->_refCount);
} else
{
_ = Interlocked.Decrement(ref entry->_refCount);
@@ -157,41 +166,6 @@ namespace StgSharp.HighPerformance.Memory
nuint origin
);
- public ref struct CacheLine : IDisposable
- {
-
- private ref int _activeCount;
- private ref int _refCount;
- private nuint _handle;
-
- internal CacheLine(
- nuint handle,
- ref int activeCount,
- ref int cacheRefCount
- )
- {
- _handle = handle;
- _refCount = ref cacheRefCount;
- _activeCount = ref activeCount;
- }
-
- [Obsolete("You should not create a CacheLineHandle outside a L4", true)]
- public CacheLine() { }
-
- public nuint Address => _handle;
-
- public void Dispose()
- {
- if (_handle == 0) {
- return;
- }
- _handle = 0;
- _ = Interlocked.Decrement(ref _activeCount);
- _ = Interlocked.Decrement(ref _refCount);
- }
-
- }
-
private struct CacheLineData
{
@@ -200,4 +174,39 @@ namespace StgSharp.HighPerformance.Memory
}
}
+
+ public ref struct L4CacheLine : IDisposable
+ {
+
+ private ref int _activeCount;
+ private ref int _refCount;
+ private nuint _handle;
+
+ internal L4CacheLine(
+ nuint handle,
+ ref int activeCount,
+ ref int cacheRefCount
+ )
+ {
+ _handle = handle;
+ _refCount = ref cacheRefCount;
+ _activeCount = ref activeCount;
+ }
+
+ [Obsolete("You should not create a CacheLineHandle outside a L4", true)]
+ public L4CacheLine() { }
+
+ public readonly nuint Address => _handle;
+
+ public void Dispose()
+ {
+ if (_handle == 0) {
+ return;
+ }
+ _handle = 0;
+ _ = Interlocked.Decrement(ref _activeCount);
+ _ = Interlocked.Decrement(ref _refCount);
+ }
+
+ }
}
diff --git a/StgSharp.Mathematics/Numeric/Linear/Matrix.cs b/StgSharp.Mathematics/Numeric/Linear/Matrix.cs
index 7a084c8b..d584c84a 100644
--- a/StgSharp.Mathematics/Numeric/Linear/Matrix.cs
+++ b/StgSharp.Mathematics/Numeric/Linear/Matrix.cs
@@ -64,7 +64,10 @@ namespace StgSharp.Mathematics.Numeric
{
get
{
- if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
+ if ((y < 0) ||
+ (y > _size.ElementColumnLength) ||
+ (x < 0) ||
+ (x > _size.ElementRowLength)) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
@@ -75,7 +78,10 @@ namespace StgSharp.Mathematics.Numeric
}
set
{
- if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
+ if ((y < 0) ||
+ (y > _size.ElementColumnLength) ||
+ (x < 0) ||
+ (x > _size.ElementRowLength)) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
@@ -106,8 +112,8 @@ namespace StgSharp.Mathematics.Numeric
ReadOnlySpan row
]
{
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
+ get => throw new NotImplementedException();
+ set => throw new NotImplementedException();
}
///
@@ -122,11 +128,7 @@ namespace StgSharp.Mathematics.Numeric
public MatrixLayout Layout { get; init; }
- internal MatrixKernel* Buffer
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => (MatrixKernel*)_buffer.BufferPointer;
- }
+ internal MatrixKernel* Buffer => (MatrixKernel*)_buffer.BufferPointer;
protected internal int KernelColumnLength => _size.KernelColumnLength;
@@ -138,9 +140,9 @@ namespace StgSharp.Mathematics.Numeric
int y
)
{
- return ref _boarder.IsInBuffer(x, y, in _size) ?
- ref _buffer[_boarder.GetIndexOffset(x, y, in _size)] :
- ref Unsafe.NullRef>();
+ return ref (_boarder.IsInBuffer(x, y, in _size) ?
+ ref _buffer[_boarder.GetIndexOffset(x, y, in _size)] :
+ ref Unsafe.NullRef>());
}
internal long GetElementOffset(
@@ -158,7 +160,7 @@ namespace StgSharp.Mathematics.Numeric
}
long kernelOffset = _boarder.GetIndexOffset(k_r, k_c, in _size);
- return kernelOffset * 16 + 4 * r + c;
+ return (kernelOffset * 16) + (4 * r) + c;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -195,8 +197,6 @@ namespace StgSharp.Mathematics.Numeric
// Caller guarantees: indices in range, layout is dense square.
int k_c = y / 4;
int k_r = x / 4;
- int c = y % 4;
- int r = x % 4;
return ref _buffer[_boarder.GetIndexOffset(k_c, k_r, in _size)];
}
diff --git a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs
index f9078d74..3b3c4be5 100644
--- a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs
+++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Sequential.cs
@@ -30,6 +30,7 @@ using StgSharp.Mathematics.Numeric.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
@@ -71,34 +72,45 @@ namespace StgSharp.Mathematics.Numeric.Linear
t->Mat1 = (MatrixKernel*)leftPtr;
t->Mat2 = (MatrixKernel*)rightPtr;
t->Mat3 = (MatrixKernel*)ansPtr;
- t->ElementType = MatrixElementType.F64;
+ t->ElementType = f32;
+ t->ComputeHandle = MatrixIntrinsicHandle.Add;
t->Scalar.Data(0) = count;
+ SequentialOperation(t, count);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void SequentialOperation(
+ MatrixParallelTask* task,
+ long count
+ )
+ {
+ MatrixElementType elementType = task->ElementType;
MatrixParallelThread[] pool;
+ MkProc op = (MkProc)NumericalModule.GlobalContext.
+ mat_mk[elementType.IntrinsicNode].
+ Get(task->ComputeHandle);
if (count <= 256)
{
- add(t);
-
- // .buffer_add(leftPtr, rightPtr, ansPtr, count);
-
+ op(task);
return;
} else if (count <= 1024)
{
pool = MatrixParallel.LeadParallel(1);
- add(t);
+ op(task);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
- pool = MatrixParallel.LeadParallel((int)(count / 1024));
- MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(pool, t);
-
+ pool = MatrixParallel.LeadParallel(count / 1024);
+ MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(pool, task);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
- return;
}
private struct SequentialPredictor : IMatrixPredictor
{
+ public static PredictPolicy Policy => PredictPolicy.Sequential;
+
public bool Predict(
Span node,
out int count
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs
index fbbcc8e1..e82be8a3 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs
@@ -45,7 +45,7 @@ namespace StgSharp.Mathematics.Numeric
private class AwaitingQueue
{
- private Element _quickElements = new();
+ private Element _quickElements;
private volatile int _count;
private readonly Queue _fallback = [];
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs
index 7a1c9d65..c170defe 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs
@@ -51,7 +51,7 @@ namespace StgSharp.Mathematics.Numeric
internal static unsafe MatrixParallelWrap ScheduleTask(
MatrixParallelThread[] workers,
MatrixParallelTask* package
- ) where TTask : IPrefetchPredict
+ ) where TTask : IL4Predict
{
/*
int primCount = package->PrimCount;
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Source.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Source.cs
deleted file mode 100644
index 7939a38b..00000000
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Source.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace StgSharp.Mathematics.Numeric.Runtime
-{
- internal class MatrixParallel
- {
-
-
- public MatrixParallelTask BaseTask { get; set; }
- public
-
- }
-}
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs
index 0575feb1..a96ef1d5 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.Predictor.cs
@@ -34,6 +34,16 @@ using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric.Runtime
{
- internal interface IMatrixPredictor : IPrefetchPredict
- where TSelf : unmanaged, IMatrixPredictor { }
+ internal interface IMatrixPredictor : IL4Predict
+ where TSelf : unmanaged, IMatrixPredictor
+ {
+ static abstract PredictPolicy Policy { get; }
+
+ }
+
+ internal enum PredictPolicy
+ {
+ Transparent = 0,
+ Sequential = 1,
+ }
}
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs
index 362c618c..94de2561 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs
@@ -43,22 +43,23 @@ namespace StgSharp.Mathematics.Numeric
{
private static readonly ConcurrentStack _recycle = [];
- private ulong _cursor;
- private ulong _maxCount;
+ private long _cursor;
+ private long _maxCount;
private MatrixParallelQueue() { }
public MatrixParallelTask* BaseTask { get; private set; }
public static MatrixParallelQueue Rent(
- MatrixParallelTask* pack
+ MatrixParallelTask* pack,
+ long count
)
{
if (!_recycle.TryPop(out MatrixParallelQueue? queue)) {
queue = new MatrixParallelQueue();
}
queue.BaseTask = pack;
- queue._maxCount = ((ulong)pack->CommonX) * ((ulong)pack->CommonY);
+ queue._maxCount = count;
queue._cursor = 0;
return queue;
}
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs
index c4c0aa52..2aa539f7 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs
@@ -49,7 +49,8 @@ namespace StgSharp.Mathematics.Numeric
{
private IntrinsicContext* _context;
- private volatile bool _disposed, _isRetireRequested = false;
+ private MatrixParallelTask* _currentTask;
+ private volatile bool _disposed, _isRetireRequested ;
private readonly ManualResetEventSlim _resetEvent;
private readonly Thread _managedThread;
@@ -67,8 +68,6 @@ namespace StgSharp.Mathematics.Numeric
public ThreadPriority AfterWork { get; set; }
- internal ManualResetEventSlim? LeaderEvent { get; set; }
-
internal ref readonly IntrinsicContext Intrinsic => ref (*_context);
internal bool IsSingle { get; set; }
@@ -91,6 +90,16 @@ namespace StgSharp.Mathematics.Numeric
_resetEvent.Set();
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void SetSingleThreadTask(
+ ref MatrixParallelTask task
+ )
+ {
+ if (IsSingle) {
+ *_currentTask = task;
+ }
+ }
+
protected virtual void Dispose(
bool disposing
)
@@ -117,6 +126,7 @@ namespace StgSharp.Mathematics.Numeric
_ = Thread.Yield();
SIMDID feature = new(GetSimdId());
IntrinsicContext* contextPtr = stackalloc IntrinsicContext[1];
+ MatrixParallelTask* taskPtr = stackalloc MatrixParallelTask[4];
LoadIntrinsicFunction(contextPtr, feature.Mask);
_context = contextPtr;
State = MatrixThreadState.Ready;
@@ -134,11 +144,11 @@ namespace StgSharp.Mathematics.Numeric
_managedThread.Priority = ThreadPriority.Highest;
if (IsSingle)
{
- // TODO 将外部线程绑定到当前线程上,并执行任务包
+ MatrixParallelTask* outer = _currentTask;
+ IsSingle = false;
} else
{
MatrixParallelQueue taskQueue = BindedWrap.TaskQueue;
- MatrixParallelTask* p = taskQueue.BaseTask;
/*
if (0 > (int)p ->ComputeHandle) {
SpecialBufferCompute(p);
@@ -162,19 +172,19 @@ namespace StgSharp.Mathematics.Numeric
#pragma warning disable CA5393
[LibraryImport(Native.LibName, EntryPoint = "sn_get_simd_level_local")]
- [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
+ [UnmanagedCallConv(CallConvs = [ typeof(CallConvCdecl) ])]
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
internal static partial ulong GetSimdId();
[LibraryImport(Native.LibName, EntryPoint = "sn_set_thread_affinity")]
- [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
+ [UnmanagedCallConv(CallConvs = [ typeof(CallConvCdecl) ])]
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
internal static partial void SetThreadAffinity(
int coreId
);
[LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")]
- [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
+ [UnmanagedCallConv(CallConvs = [ typeof(CallConvCdecl) ])]
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
private static unsafe partial void LoadIntrinsicFunction(
IntrinsicContext* context,
diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelWrap.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelWrap.cs
index c6f8f51a..b4daf9da 100644
--- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelWrap.cs
+++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelWrap.cs
@@ -26,6 +26,7 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Collections;
+using StgSharp.HighPerformance.Memory;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
@@ -59,25 +60,16 @@ namespace StgSharp.Mathematics.Numeric
)
{
_threads = threadArray;
- IsMultithread = threadArray.Length > 1;
_countdownEvent = new CountdownEvent(threadArray.Length);
}
- public ReadOnlySpan Threads
- {
- get
- {
- ObjectDisposedException.ThrowIf(_disposed, nameof(MatrixParallelWrap));
-
- return _threads;
- }
- }
+ public ReadOnlySpan Threads => _disposed ? [] : _threads;
public ThreadPriority AfterWork { get; private set; }
- internal MatrixParallelQueue TaskQueue { get; set; }
+ internal L4 DataCache { get; set; }
- private bool IsMultithread { get; init; }
+ internal MatrixParallelQueue TaskQueue { get; set; }
public void Dispose()
{
@@ -90,6 +82,7 @@ namespace StgSharp.Mathematics.Numeric
SleepMode afterWork
)
{
+ ObjectDisposedException.ThrowIf(_disposed, nameof(MatrixParallelWrap));
AfterWork = (ThreadPriority)afterWork;
foreach (MatrixParallelThread thread in _threads)
{
@@ -101,7 +94,9 @@ namespace StgSharp.Mathematics.Numeric
public void WaitAllWraps()
{
- ObjectDisposedException.ThrowIf(_disposed, nameof(MatrixParallelWrap));
+ if (_disposed) {
+ return;
+ }
_countdownEvent.Wait();
}
diff --git a/StgSharp.Native/StgSharp.Native.vcxproj b/StgSharp.Native/StgSharp.Native.vcxproj
index 215167c9..65b3a599 100644
--- a/StgSharp.Native/StgSharp.Native.vcxproj
+++ b/StgSharp.Native/StgSharp.Native.vcxproj
@@ -172,7 +172,7 @@
-
+
diff --git a/StgSharp.Native/StgSharp.Native.vcxproj.filters b/StgSharp.Native/StgSharp.Native.vcxproj.filters
index b2ea2a86..f0b379d9 100644
--- a/StgSharp.Native/StgSharp.Native.vcxproj.filters
+++ b/StgSharp.Native/StgSharp.Native.vcxproj.filters
@@ -39,7 +39,7 @@
源文件
-
+
源文件
diff --git a/StgSharp.Native/sn-src/m.basic.x86.c b/StgSharp.Native/sn-src/m.transpose.x86.c
similarity index 100%
rename from StgSharp.Native/sn-src/m.basic.x86.c
rename to StgSharp.Native/sn-src/m.transpose.x86.c
diff --git a/StgSharp.Native/sn-src/simdid.x86.c b/StgSharp.Native/sn-src/simdid.x86.c
index 84dacc9c..f35f350b 100644
--- a/StgSharp.Native/sn-src/simdid.x86.c
+++ b/StgSharp.Native/sn-src/simdid.x86.c
@@ -141,7 +141,7 @@ SN_API SIMDID SN_DECL sn_get_simd_level_local()
const int is_amd = (strcmp(vendor, "AuthenticAMD") == 0);
const int is_hygon = (strcmp(vendor, "HygonGenuine") == 0);
const int is_centaur = (strcmp(vendor, "CentaurHauls") == 0);
- const int is_zhaoxin = (memcmp(vendor, " Shanghai ", 12) == 0);
+ const int is_zhaoxin = (strcmp(vendor, " Shanghai ") == 0);
const int is_via = is_centaur || is_zhaoxin;
get_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
@@ -350,23 +350,4 @@ SN_API SIMDID SN_DECL sn_get_simd_level_global()
return global_simdid;
}
-#else
-
-SN_API SIMDID SN_DECL sn_get_simd_level_local()
-{
- SIMDID simdid;
- simdid.mask = 0;
- return simdid;
-}
-
-SN_API SIMDID SN_DECL sn_get_simd_level_global()
-{
- if (global_simdid.mask) {
- return global_simdid;
- }
-
- global_simdid = sn_get_simd_level_local();
- return global_simdid;
-}
-
#endif
diff --git a/StgSharp.UserInterface/View/PresentorDescription.cs b/StgSharp.UserInterface/View/PresentorDescription.cs
index f4139202..0925443c 100644
--- a/StgSharp.UserInterface/View/PresentorDescription.cs
+++ b/StgSharp.UserInterface/View/PresentorDescription.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace StgSharp.UnserInterface.View
{
- internal class PresentorDescription
+ internal class PresenterDescription
{
}
}
diff --git a/StgSharpDebug/TestL4.cs b/StgSharpDebug/TestL4.cs
index 4c3134fd..315a9c6c 100644
--- a/StgSharpDebug/TestL4.cs
+++ b/StgSharpDebug/TestL4.cs
@@ -38,7 +38,7 @@ namespace StgSharp
// 仅供 L4 内存安全测试使用。
// ====================================================================
- internal sealed unsafe class SequentialPredictor : IPrefetchPredict
+ internal sealed unsafe class SequentialPredictor : IL4Predict
{
private readonly nuint[] _addresses;
@@ -313,7 +313,7 @@ namespace StgSharp
{
nuint[] result = new nuint[count];
for (int i = 0; i < count; i++) {
- result[i] = (nuint)(0x1_0000_0000UL + (ulong)i * 0x1000);
+ result[i] = (nuint)(0x1_0000_0000UL + (((ulong)i) * 0x1000));
}
return result;
}
diff --git a/StgSharpDebug/TestL4Behaviour.cs b/StgSharpDebug/TestL4Behaviour.cs
index fe8002ae..c01acba1 100644
--- a/StgSharpDebug/TestL4Behaviour.cs
+++ b/StgSharpDebug/TestL4Behaviour.cs
@@ -40,7 +40,7 @@ namespace StgSharp
// WriteBack 记录被回写的 origin,供驱逐测试断言。
// ====================================================================
- internal sealed unsafe class TrackingPredictor : IPrefetchPredict
+ internal sealed unsafe class TrackingPredictor : IL4Predict
{
private readonly nuint[] _addresses;
@@ -128,7 +128,10 @@ namespace StgSharp
private static unsafe byte L4ReadFirstByte(
L4.CacheLine line
- ) => *(byte*)line.Address;
+ )
+ {
+ return *(byte*)line.Address;
+ }
// ================================================================
// P1-2 AgeAll_SaturatesAt3
@@ -168,7 +171,7 @@ namespace StgSharp
for (int i = 0; i < snap.MaxId; i++) {
L4Assert(
snap.RrpvSnapshot[i] == 0,
- $"RrpvSnapshot[{i}] should be 0 right after Map, " + $"got {snap.RrpvSnapshot[i]}");
+ $"{$"RrpvSnapshot[{i}] should be 0 right after Map, "}{$"got {snap.RrpvSnapshot[i]}"}");
}
}
@@ -191,7 +194,7 @@ namespace StgSharp
if (snap.RrpvSnapshot[i] != 3)
{
L4Assert(false,
- $"RrpvSnapshot[{i}] == {snap.RrpvSnapshot[i]}, " + "expected 3 after 4x AgeAll (saturation failure or overflow)");
+ $"{$"RrpvSnapshot[{i}] == {snap.RrpvSnapshot[i]}, "}expected 3 after 4x AgeAll (saturation failure or overflow)");
allSaturated = false;
}
}
@@ -305,7 +308,7 @@ namespace StgSharp
}
L4Assert(
evictedOrigin != nuint.Zero,
- $"WriteBack origin should be a batch1 address, " + $"WriteBackLog=[{string.Join(", ", predictor2.WriteBackLog)}]");
+ $"{$"WriteBack origin should be a batch1 address, "}{($"WriteBackLog=[{string.Join(", ", predictor2.WriteBackLog)}]")}");
// 断言 c: SwissTable 中已不含该 origin
L4Assert(
@@ -320,11 +323,11 @@ namespace StgSharp
remapped.Dispose();
L4Assert(
refill == 0xCC,
- $"Re-mapped evicted line should be re-prefetched with 0xCC, " + $"got 0x{refill:X2} (0xAA = stale data not evicted)");
+ $"{$"Re-mapped evicted line should be re-prefetched with 0xCC, "}{($"got 0x{refill:X2} (0xAA = stale data not evicted)")}");
if (_l4FailCount == 0) {
Console.WriteLine(
- $"PASS (evicted 0x{evictedOrigin:X}, remain={remain}, " + $"WriteBack×{predictor2.WriteBackLog.Count})");
+ $"{($"PASS (evicted 0x{evictedOrigin:X}, remain={remain}, ")}{$"WriteBack×{predictor2.WriteBackLog.Count})"}");
}
}
catch (Exception ex)
diff --git a/StgSharpDebug/TestL4Prefetch.cs b/StgSharpDebug/TestL4Prefetch.cs
index 9b8af875..4868ae8d 100644
--- a/StgSharpDebug/TestL4Prefetch.cs
+++ b/StgSharpDebug/TestL4Prefetch.cs
@@ -40,7 +40,7 @@ namespace StgSharp
// 用于 P2-2 验证"预填充后 Map 命中不触发二次 Prefetch"。
// ====================================================================
- internal sealed class CountingPredictor : IPrefetchPredict
+ internal sealed class CountingPredictor : IL4Predict
{
private readonly nuint[] _addresses;
@@ -158,7 +158,7 @@ namespace StgSharp
L4.DebugSnapshot snap = l4.GetDebugSnapshot();
Console.WriteLine();
Console.WriteLine(
- $" [diag] after warm-up: MaxId={snap.MaxId}, " + $"AheadCount={snap.AheadCount}, " + $"Predict×{predictAfterWarmup}, " + $"Prefetch×{prefetchAfterWarmup}");
+ $"{$" [diag] after warm-up: MaxId={snap.MaxId}, "}{$"AheadCount={snap.AheadCount}, "}{$"Predict×{predictAfterWarmup}, "}{$"Prefetch×{prefetchAfterWarmup}"}");
}
// 断言 c(warm-up 后):所有 K 条地址均在缓存中
@@ -195,7 +195,7 @@ namespace StgSharp
{
L4.DebugSnapshot snap = l4.GetDebugSnapshot();
Console.WriteLine(
- $" [diag] after {K}x Map: AheadCount={snap.AheadCount}, " + $"Predict×{predictAfterMaps}, " + $"Prefetch×{prefetchAfterMaps}");
+ $"{$" [diag] after {K}x Map: AheadCount={snap.AheadCount}, "}{$"Predict×{predictAfterMaps}, "}{$"Prefetch×{prefetchAfterMaps}"}");
}
// 断言 b: 已缓存的行不会被重新装填(Prefetch(line) 调用次数不增加)
@@ -204,15 +204,15 @@ namespace StgSharp
// 这是预期行为,不断言 Predict 次数。
L4Assert(
prefetchAfterMaps == prefetchAfterWarmup,
- $"Prefetch(line) should not be called again for already-cached addresses, " + $"was {prefetchAfterWarmup} after warm-up, now {prefetchAfterMaps}");
+ $"{$"Prefetch(line) should not be called again for already-cached addresses, "}{$"was {prefetchAfterWarmup} after warm-up, now {prefetchAfterMaps}"}");
// Predict 增加是正常的,仅打印供参考
Console.WriteLine(
- $" [info] Predict called {predictAfterMaps - predictAfterWarmup} " + $"extra time(s) during {K}x Map " + $"(aheadCount stays below threshold=1024 " + $"because K={K} << 1024, re-prediction is expected)");
+ $"{$" [info] Predict called {predictAfterMaps - predictAfterWarmup} "}{$"extra time(s) during {K}x Map "}{$"(aheadCount stays below threshold=1024 "}{$"because K={K} << 1024, re-prediction is expected)"}");
if (_l4FailCount == 0) {
Console.WriteLine(
- $"PASS (K={K}, all hits, no re-prefetch, " + $"Prefetch×{prefetchAfterMaps})");
+ $"{$"PASS (K={K}, all hits, no re-prefetch, "}{$"Prefetch×{prefetchAfterMaps})"}");
}
}
catch (Exception ex)
@@ -284,7 +284,7 @@ namespace StgSharp
// 此处仅记录行为,不判定 FAIL——但打印出来供后续决策参考。
Console.WriteLine(
evictThrew ?
- "PASS (DebugEvict with null Predictor threw NullRef as expected " + "— caller is responsible for null check per trusted-call model)" :
+ ("PASS (DebugEvict with null Predictor threw NullRef as expected " + "— caller is responsible for null check per trusted-call model)") :
"PASS (DebugEvict with null Predictor did not throw)");
// 核心断言:Prefetch() 本身在 null Predictor 时不崩溃
@@ -300,7 +300,7 @@ namespace StgSharp
L4.DebugSnapshot snap = l4b.GetDebugSnapshot();
Console.WriteLine(
- $" [info] AheadCount after warm-up = {snap.AheadCount} " + $"(Prefetch triggers when < 1024)");
+ $"{$" [info] AheadCount after warm-up = {snap.AheadCount} "}{$"(Prefetch triggers when < 1024)"}");
// Prefetch 的 null 检查测试:直接调用 DebugPrefetch(如已暴露)
// 当前 Debug 接口未暴露 DebugPrefetch,改为间接验证: