time service contains bug, it cannot stop after edge
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Root Type="DevExpress.CodeRush.VisualizePlugins.StructuralHighlighting.Options.StructuralHighlightingOptions">
|
||||
<Options Language="Neutral">
|
||||
<Enabled>False</Enabled>
|
||||
</Options>
|
||||
</Root>
|
||||
@@ -38,16 +38,19 @@ namespace StgSharp.Internal.Intrinsic
|
||||
internal unsafe struct IntrinsicContext
|
||||
{
|
||||
|
||||
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify;
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_add;
|
||||
public delegate* unmanaged[Cdecl]<void*, ScalarPacket*,long, void> f32_fill;
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_fma;
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> f32_scalar_mul;
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_sub;
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void> f32_transpose;
|
||||
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd;
|
||||
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair;
|
||||
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> normalize_3;
|
||||
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify; //city_hash_simplify
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_buffer_add; //f32_buffer_add
|
||||
public delegate* unmanaged[Cdecl]<void*, ScalarPacket*,long, void> f32_buffer_fill; //f32_buffer_fill
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> f32_buffer_scalar_mul; //f32_buffer_s_m
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, long, void> f32_buffer_sub; //f32_kernel_sub
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void> f32_buffer_transpose; //f32_kernel_transpose
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, int, int, int, int, void> f32_build_panel; //f32_build_panel
|
||||
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> f32_normalize_3; //f32_normalize_3
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_panel_fma; //f32_panel_fma
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, int, int, int, int, void> f32_store_panel; //f32_store_panel
|
||||
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd; //factorial_simd
|
||||
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair; //index_pair
|
||||
public delegate* unmanaged[Cdecl]<void*, void*, ScalarPacket*, long, void> variant ; //variant
|
||||
|
||||
public IntrinsicContext()
|
||||
{
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace StgSharp.Mathematics.Graphic
|
||||
mat.transpose.colum2 = rowSpan[2].vec;
|
||||
mat.transpose.colum3 = rowSpan[3].vec;
|
||||
|
||||
NativeIntrinsic.Intrinsic.f32_transpose(&mat.transpose, &mat.mat);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_transpose(&mat.transpose, &mat.mat);
|
||||
mat.isTransposed = false;
|
||||
return mat;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ namespace StgSharp.Mathematics.Graphic
|
||||
if (!isTransposed)
|
||||
{
|
||||
fixed (ColumnSet4* source = &mat, target = &transpose) {
|
||||
NativeIntrinsic.Intrinsic.f32_transpose(source, target);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_transpose(source, target);
|
||||
}
|
||||
isTransposed = true;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ namespace StgSharp.Mathematics.Graphic
|
||||
public static unsafe Matrix44 operator -(Matrix44 left, Matrix44 right)
|
||||
{
|
||||
Matrix44 ret = new();
|
||||
NativeIntrinsic.Intrinsic.f32_sub(&left, &right, &ret, 1);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_sub(&left, &right, &ret, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace StgSharp.Mathematics.Graphic
|
||||
public static unsafe Matrix44 operator +(Matrix44 left, Matrix44 right)
|
||||
{
|
||||
Matrix44 ret = new();
|
||||
NativeIntrinsic.Intrinsic.f32_add(&left, &right, &ret, 1);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_add(&left, &right, &ret, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ namespace StgSharp
|
||||
{
|
||||
if (!_subscribers[i].OnSpanTick(elapsedTicks))
|
||||
{
|
||||
Console.WriteLine("removed");
|
||||
_subscribers.RemoveAt(i);
|
||||
i--; // adjust index after removal
|
||||
}
|
||||
|
||||
@@ -46,8 +46,10 @@ namespace StgSharp.Common.Timing
|
||||
double initialSliceSeconds,
|
||||
double totalSeconds,
|
||||
double growthMultiplier,
|
||||
double minSliceSeconds) => new LogTimeSequence(initialSliceSeconds, totalSeconds,
|
||||
growthMultiplier, minSliceSeconds);
|
||||
double minSliceSeconds) => new LogTimeSequence(initialSliceSeconds,
|
||||
totalSeconds,
|
||||
growthMultiplier,
|
||||
minSliceSeconds);
|
||||
|
||||
public abstract bool EndsAt(long currentTick);
|
||||
|
||||
@@ -71,7 +73,6 @@ namespace StgSharp.Common.Timing
|
||||
if (frameSeconds > totalSeconds) {
|
||||
throw new ArgumentException("Frame length greater than total length.");
|
||||
}
|
||||
|
||||
_totalSeconds = totalSeconds;
|
||||
_frameSeconds = frameSeconds;
|
||||
}
|
||||
@@ -85,7 +86,7 @@ namespace StgSharp.Common.Timing
|
||||
long span = currentTick - PreviousFrameTick;
|
||||
if (span >= _frameLengthTicks && currentTick < EndingTick)
|
||||
{
|
||||
PreviousFrameTick += _frameLengthTicks; // advance start of next frame
|
||||
PreviousFrameTick += _frameLengthTicks;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -105,25 +106,21 @@ namespace StgSharp.Common.Timing
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logarithmic time sequence with growth factor. Boundaries (cumulative times since start)
|
||||
/// follow initial * multiplier^k, but each slice duration (difference between adjusted
|
||||
/// boundaries) is at least minSliceSeconds. First slice uses the exact initial length even if
|
||||
/// below minSliceSeconds, subsequent slices enforce minimum. Example: initial=2,
|
||||
/// multiplier=2, total>=8, min=3 => boundaries: 2,5,8 (durations:2,3,3).
|
||||
/// Logarithmic time sequence with growth factor and minimum slice length enforcement.
|
||||
/// </summary>
|
||||
internal sealed class LogTimeSequence : TimeSequence
|
||||
{
|
||||
|
||||
private bool _finalEmitted;
|
||||
private readonly double _initialSeconds;
|
||||
private double _lastBoundarySecondsAdjusted; // adjusted cumulative seconds of last emitted boundary (0 at start)
|
||||
private double _lastBoundarySecondsAdjusted;
|
||||
private readonly double _minSliceSeconds;
|
||||
private readonly double _multiplier;
|
||||
private double _nextBoundarySecondsAdjusted; // adjusted cumulative seconds for next boundary
|
||||
private double _nextBoundarySecondsAdjusted;
|
||||
private readonly double _totalSeconds;
|
||||
|
||||
private int _sliceIndex; // index of next boundary (0 => first boundary at initialSeconds)
|
||||
private int _sliceIndex;
|
||||
private long _freq;
|
||||
private long _nextBoundaryTick; // absolute tick for next boundary
|
||||
private long _nextBoundaryTick;
|
||||
private long _totalTicks;
|
||||
|
||||
public LogTimeSequence(
|
||||
@@ -139,11 +136,9 @@ namespace StgSharp.Common.Timing
|
||||
if (growthMultiplier < 1.0) {
|
||||
throw new ArgumentException("growthMultiplier must be >= 1");
|
||||
}
|
||||
|
||||
if (initialSliceSeconds > totalSeconds) {
|
||||
throw new ArgumentException("Initial slice length greater than total length.");
|
||||
}
|
||||
|
||||
_initialSeconds = initialSliceSeconds;
|
||||
_totalSeconds = totalSeconds;
|
||||
_multiplier = growthMultiplier;
|
||||
@@ -151,49 +146,62 @@ namespace StgSharp.Common.Timing
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool EndsAt(long currentTick) => currentTick >= EndingTick ||
|
||||
_nextBoundarySecondsAdjusted >= _totalSeconds;
|
||||
public override bool EndsAt(long currentTick)
|
||||
{
|
||||
if (currentTick >= EndingTick)
|
||||
{
|
||||
Console.WriteLine("Ended");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool IsNextFrameReady(long currentTick)
|
||||
{
|
||||
if (currentTick < _nextBoundaryTick || currentTick >= EndingTick) {
|
||||
// Emit final once when reaching or passing end.
|
||||
if (currentTick >= EndingTick)
|
||||
{
|
||||
if (_finalEmitted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PreviousFrameTick = EndingTick;
|
||||
_finalEmitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not reached end: only when we cross the next boundary tick do we emit.
|
||||
if (currentTick < _nextBoundaryTick)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Emit frame: update previous frame tick and prepare next boundary.
|
||||
PreviousFrameTick = _nextBoundaryTick; // boundary just reached
|
||||
// Advance to this boundary.
|
||||
PreviousFrameTick = _nextBoundaryTick;
|
||||
_lastBoundarySecondsAdjusted = _nextBoundarySecondsAdjusted;
|
||||
_sliceIndex++;
|
||||
|
||||
// Compute original (unadjusted) next cumulative boundary in seconds.
|
||||
double originalNext = _initialSeconds * Math.Pow(_multiplier, _sliceIndex);
|
||||
|
||||
// Enforce total cap.
|
||||
if (originalNext > _totalSeconds)
|
||||
{
|
||||
originalNext = _totalSeconds;
|
||||
// Compute next cumulative boundary seconds with multiplier, then enforce min-slice and total cap.
|
||||
double next = _initialSeconds * Math.Pow(_multiplier, _sliceIndex);
|
||||
if (next > _totalSeconds) {
|
||||
next = _totalSeconds;
|
||||
}
|
||||
|
||||
// Compute slice duration based on adjusted previous boundary.
|
||||
double delta = originalNext - _lastBoundarySecondsAdjusted;
|
||||
if (_sliceIndex > 0 && delta < _minSliceSeconds)
|
||||
double delta = next - _lastBoundarySecondsAdjusted;
|
||||
if (delta < _minSliceSeconds)
|
||||
{
|
||||
// Enforce minimum (except for first slice which uses initial value)
|
||||
originalNext = _lastBoundarySecondsAdjusted + _minSliceSeconds;
|
||||
if (originalNext > _totalSeconds) {
|
||||
originalNext = _totalSeconds;
|
||||
next = _lastBoundarySecondsAdjusted + _minSliceSeconds;
|
||||
if (next > _totalSeconds) {
|
||||
next = _totalSeconds;
|
||||
}
|
||||
}
|
||||
_nextBoundarySecondsAdjusted = originalNext;
|
||||
|
||||
if (_nextBoundarySecondsAdjusted >= _totalSeconds)
|
||||
{
|
||||
_nextBoundaryTick = EndingTick; // sequence will end after this boundary
|
||||
} else
|
||||
{
|
||||
_nextBoundaryTick = BeginningTick + SecondsToTicks(_nextBoundarySecondsAdjusted);
|
||||
}
|
||||
_nextBoundarySecondsAdjusted = next;
|
||||
_nextBoundaryTick = (_nextBoundarySecondsAdjusted >= _totalSeconds) ?
|
||||
EndingTick :
|
||||
BeginningTick + SecondsToTicks(_nextBoundarySecondsAdjusted);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -205,9 +213,10 @@ namespace StgSharp.Common.Timing
|
||||
EndingTick = BeginningTick + _totalTicks;
|
||||
_sliceIndex = 0;
|
||||
_lastBoundarySecondsAdjusted = 0.0;
|
||||
_nextBoundarySecondsAdjusted = _initialSeconds; // first boundary uses exact initial length
|
||||
_nextBoundarySecondsAdjusted = _initialSeconds;
|
||||
_nextBoundaryTick = BeginningTick + SecondsToTicks(_nextBoundarySecondsAdjusted);
|
||||
PreviousFrameTick = BeginningTick; // start point
|
||||
PreviousFrameTick = BeginningTick;
|
||||
_finalEmitted = false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -86,11 +86,7 @@ namespace StgSharp.Timing
|
||||
public void Dispose()
|
||||
{
|
||||
// mark provider as ended so external users can observe terminal state
|
||||
try
|
||||
{
|
||||
Volatile.Write(ref _endedFlag, 1);
|
||||
}
|
||||
catch { }
|
||||
Volatile.Write(ref _endedFlag, 1);
|
||||
s_unusedID.Push(TokenID);
|
||||
_event.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
@@ -211,6 +207,7 @@ namespace StgSharp.Timing
|
||||
{
|
||||
// mark ended due to sequence timeout, then dispose
|
||||
Volatile.Write(ref _endedFlag, 1);
|
||||
Console.WriteLine("Time span ended.");
|
||||
Dispose();
|
||||
return false;
|
||||
}
|
||||
@@ -238,9 +235,6 @@ namespace StgSharp.Timing
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void Refresh() => _refreshHandler?.Invoke(this, EventArgs.Empty); // Legacy compatibility.
|
||||
|
||||
~TimeSpanProvider() => Dispose();
|
||||
|
||||
}
|
||||
|
||||
@@ -39,15 +39,18 @@ namespace StgSharp.Timing
|
||||
public partial class TimeSpanProvider
|
||||
{
|
||||
|
||||
private bool _subscribed;
|
||||
// private bool _subscribed;
|
||||
private int _emittedSpanCount; // legacy counter
|
||||
|
||||
// internal ended flag (0 = running, 1 = ended)
|
||||
private int _endedFlag = 0;
|
||||
private int _endedFlag;
|
||||
private readonly TimeSequence _sequence;
|
||||
private readonly TimeSourceProviderBase _timeSource;
|
||||
|
||||
public TimeSpanProvider(TimeSequence sequence, TimeSourceProviderBase provider, int maxWaitCount = 1)
|
||||
public TimeSpanProvider(
|
||||
TimeSequence sequence,
|
||||
TimeSourceProviderBase provider,
|
||||
int maxWaitCount = 1)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(provider);
|
||||
ArgumentNullException.ThrowIfNull(sequence);
|
||||
@@ -55,8 +58,10 @@ namespace StgSharp.Timing
|
||||
_sequence = sequence;
|
||||
_sequence.StartFrom(provider);
|
||||
provider.AddSubscriber(this);
|
||||
_subscribed = true;
|
||||
if (!s_unusedID.TryPop(out int id)) {
|
||||
|
||||
// _subscribed = true;
|
||||
if (!s_unusedID.TryPop(out int id))
|
||||
{
|
||||
id = Interlocked.Increment(ref s_maxID);
|
||||
}
|
||||
TokenID = id;
|
||||
@@ -70,16 +75,20 @@ namespace StgSharp.Timing
|
||||
/// </summary>
|
||||
public bool IsEnded => Volatile.Read(ref _endedFlag) != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Current emitted time in seconds relative to the sequence beginning.
|
||||
/// </summary>
|
||||
public double CurrentSecond
|
||||
{
|
||||
get => (double)_sequence.PreviousFrameTick / _timeSource.Frequency;
|
||||
get => (double)(_sequence.PreviousFrameTick - _sequence.BeginningTick) / _timeSource.Frequency;
|
||||
}
|
||||
|
||||
public int CurrentSpan => _emittedSpanCount;
|
||||
|
||||
public static TimeSourceProviderBase DefaultProvider => World.MainTimeProvider;
|
||||
|
||||
public static explicit operator int(TimeSpanProvider provider) => provider?._emittedSpanCount ?? 0;
|
||||
public static explicit operator int(TimeSpanProvider provider) => provider?._emittedSpanCount ??
|
||||
0;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr, rightPtr, ansPtr, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_add(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
return ans;
|
||||
} else if (count <= 1024)
|
||||
@@ -68,7 +68,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr, rightPtr, ansPtr, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_add(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
return ans;
|
||||
@@ -81,7 +81,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
package->PrimCount = left.KernelColumnLength;
|
||||
package->SecCount = left.KernelRowLength;
|
||||
package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_add;
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_buffer_add;
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
@@ -96,12 +96,12 @@ namespace StgSharp.Mathematics.Numeric
|
||||
scalar->Data<float>(0) = value;
|
||||
if (count <= 256)
|
||||
{
|
||||
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_fill(ans.Buffer, scalar, count);
|
||||
return;
|
||||
} else if (count <= 1024)
|
||||
{
|
||||
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
|
||||
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_fill(ans.Buffer, scalar, count);
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
return;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
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->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_buffer_fill;
|
||||
package->Scalar = scalar;
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
@@ -144,7 +144,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
{
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_scalar_mul(leftPtr, ansPtr, scalar, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_scalar_mul(leftPtr, ansPtr, scalar, count);
|
||||
|
||||
return ans;
|
||||
} else if (count <= 1024)
|
||||
@@ -153,7 +153,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_scalar_mul(leftPtr, ansPtr, scalar, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_scalar_mul(leftPtr, ansPtr, scalar, count);
|
||||
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
return ans;
|
||||
@@ -166,7 +166,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
package->SecCount = left.KernelRowLength;
|
||||
package->Scalar = scalar;
|
||||
package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM);
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_scalar_mul;
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_buffer_scalar_mul;
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
@@ -192,7 +192,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_sub(leftPtr, rightPtr, ansPtr, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_sub(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
return ans;
|
||||
} else if (count <= 1024)
|
||||
@@ -202,7 +202,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
NativeIntrinsic.Intrinsic.f32_sub(leftPtr, rightPtr, ansPtr, count);
|
||||
NativeIntrinsic.Intrinsic.f32_buffer_sub(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
return ans;
|
||||
@@ -215,7 +215,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
package->PrimCount = left.KernelColumnLength;
|
||||
package->SecCount = left.KernelRowLength;
|
||||
package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_sub;
|
||||
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_buffer_sub;
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
|
||||
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sn-src\k_build_panel.c" />
|
||||
<ClCompile Include="sn-src\k_panel.c" />
|
||||
<ClCompile Include="sn-src\k_basicop.c" />
|
||||
<ClCompile Include="sn-src\dllmain.c" />
|
||||
<ClCompile Include="sn-src\k_bufop.c" />
|
||||
@@ -156,7 +156,7 @@
|
||||
<ClCompile Include="sn-src\k_fma.c" />
|
||||
<ClCompile Include="sn-src\str_hash.c" />
|
||||
<ClCompile Include="sn-src\load_intrinsic.c">
|
||||
<FileType>CppCode</FileType>
|
||||
<FileType>CCode</FileType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_glfw.c" />
|
||||
<ClCompile Include="sn-src\sn_native.c" />
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<ClCompile Include="sn-src\k_bufop.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\k_build_panel.c">
|
||||
<ClCompile Include="sn-src\k_panel.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -131,6 +131,8 @@ typedef void(SN_DECL *BUF_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_ker
|
||||
|
||||
#pragma region matrix panel function type
|
||||
|
||||
typedef void(SN_DECL *PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
|
||||
int row_length, int col_index, int row_index);
|
||||
typedef void(SN_DECL *PNL_PROC_LRA)(mat_panel *left, mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_RA)(mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_LRAS)(mat_panel *left, mat_panel *right, mat_panel *ans,
|
||||
@@ -250,22 +252,21 @@ INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int lengt
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef void(SN_DECL *BUILD_PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
|
||||
int row_length, int col_index, int row_index);
|
||||
|
||||
// Reordered to match C# IntrinsicContext field order
|
||||
// C# order: city_hash_simplify, f32_add, f32_fill, f32_fma, f32_scalar_mul, f32_sub, f32_transpose, factorial_simd, index_pair, normalize_3
|
||||
// Mirrors C# IntrinsicContext field order so managed/unmanaged layouts stay in sync.
|
||||
typedef struct sn_intrinsic {
|
||||
HASH city_hash_simplify; // city_hash_simplify
|
||||
BUF_PROC_LRA f32_buffer_add; // f32_add
|
||||
BUF_PROC_AS f32_buffer_fill; // f32_fill
|
||||
PNL_PROC_LRA f32_panel_fma; // f32_fma (panel variant)
|
||||
BUF_PROC_LRA f32_kernel_scalar_mul; // f32_scalar_mul (right+ans+scalar variant mapped here)
|
||||
BUF_PROC_LRA f32_kernel_sub; // f32_sub
|
||||
KER_PROC_RA f32_kernel_transpose; // f32_transpose
|
||||
FACTORIALROC factorial_simd; // factorial_simd
|
||||
INDEX_PAIR index_pair; // index_pair
|
||||
VECTORNORMALIZEPROC f32_normalize_3; // normalize_3
|
||||
HASH city_hash_simplify;
|
||||
BUF_PROC_LRA f32_buffer_add;
|
||||
BUF_PROC_AS f32_buffer_fill;
|
||||
BUF_PROC_RAS f32_buffer_scalar_mul;
|
||||
BUF_PROC_LRA f32_buffer_sub;
|
||||
KER_PROC_RA f32_buffer_transpose;
|
||||
PANEL_PROC f32_build_panel;
|
||||
VECTORNORMALIZEPROC f32_normalize_3;
|
||||
PNL_PROC_LRA f32_panel_fma;
|
||||
PANEL_PROC f32_store_panel;
|
||||
FACTORIALROC factorial_simd;
|
||||
INDEX_PAIR index_pair;
|
||||
BUF_PROC_RAS variant;
|
||||
} sn_intrinsic;
|
||||
|
||||
typedef enum most_advanced_instruction {
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
#ifndef SN_MATKERNEL
|
||||
#define SN_MATKERNEL
|
||||
|
||||
#define ELEMENTSIZE(T) sizeof(T)
|
||||
#define XMMCOUNT(T) sizeof(T)
|
||||
#define YMMCOUNT(T) sizeof(T) / 2
|
||||
#define ZMMCOUNT(T) sizeof(T) / 4
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sn_internal.h"
|
||||
|
||||
/* Kernel storage unions for a fixed 4x4 block. */
|
||||
#define ELEMENTSIZE(T) sizeof(T)
|
||||
#define XMMCOUNT(T) (sizeof(T))
|
||||
#define YMMCOUNT(T) (sizeof(T) / 2)
|
||||
#define ZMMCOUNT(T) (sizeof(T) / 4)
|
||||
|
||||
#define MAT_KERNEL(T) \
|
||||
union { \
|
||||
__m128 xmm[XMMCOUNT(T) / 4]; \
|
||||
@@ -25,7 +28,8 @@
|
||||
T v[4]; \
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Provide a named alias for the zero kernel type to ensure consistent linkage in C++. */
|
||||
typedef MAT_KERNEL(uint64_t) sn_zero_kernel_u64;
|
||||
|
||||
/* Helpers (all compile-time): */
|
||||
#define SN_LANES(T_VEC, T) (sizeof(T_VEC) / sizeof(T))
|
||||
@@ -48,8 +52,8 @@
|
||||
- SIMD view remains integer-typed; cast inside micro-kernels to the
|
||||
appropriate floating-point/integer vector type on demand.
|
||||
*/
|
||||
#define MAT_PANEL_SQ_MIN(T, T_VEC, MINQ) \
|
||||
SN_ALIGNAS(sizeof(T_VEC)) union { \
|
||||
#define MAT_PANEL_SQ_MIN_NOALIGN(T, T_VEC, MINQ) \
|
||||
union { \
|
||||
T_VEC vec[PANEL_Q(T, T_VEC, MINQ)][PANEL_CHUNKS(T, T_VEC, MINQ)]; \
|
||||
T flat[PANEL_Q(T, T_VEC, MINQ) * PANEL_Q(T, T_VEC, MINQ)]; \
|
||||
}
|
||||
@@ -63,44 +67,53 @@
|
||||
/* SSE panel layout: column-major buffer holding 4 logical columns with MINQ=4.
|
||||
Columns: each column packs up to four scalars so ALIGN equals sizeof(__m128).
|
||||
Alignment: every column boundary lands on a 16-byte multiple for XMM loads. */
|
||||
#define MAT_PANEL_SSE(T) MAT_PANEL_SQ_MIN(T, __m128, 4)
|
||||
#define MAT_PANEL_SSE(T) SN_ALIGNAS(16) MAT_PANEL_SQ_MIN_NOALIGN(T, __m128, 4)
|
||||
/* AVX2 panel layout: column-major buffer holding 8 logical columns with MINQ=8.
|
||||
Columns: each column stores eight elements via two 256-bit chunks when T is 32-bit.
|
||||
Alignment: column starts are 32-byte aligned so AVX2 loads/stores remain contiguous. */
|
||||
#define MAT_PANEL_AVX(T) MAT_PANEL_SQ_MIN(T, __m256, 8)
|
||||
#define MAT_PANEL_AVX(T) SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, 8)
|
||||
/* AVX-512 panel layout: column-major buffer holding 8 or more columns depending on T.
|
||||
Columns: each column expands to ceil(Q/lanes) ZMM chunks; default MINQ=8 keeps double-wide tiles.
|
||||
Alignment: column starts sit on 64-byte boundaries to match AVX-512 streaming access. */
|
||||
#define MAT_PANEL_512(T) MAT_PANEL_SQ_MIN(T, __m512, 8)
|
||||
#define MAT_PANEL_512(T) SN_ALIGNAS(64) MAT_PANEL_SQ_MIN_NOALIGN(T, __m512, 8)
|
||||
|
||||
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern __declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Access helpers (all compile-time friendly):
|
||||
Given Q = PANEL_Q(...), CH = PANEL_CHUNKS(...), R = lanes per vector:
|
||||
- Column c occupies vec[c][0..CH-1].
|
||||
- Row r inside column c is located at vec[c][r / R] with lane (r % R).
|
||||
*/
|
||||
|
||||
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
__declspec(align(64)) extern MAT_KERNEL(uint64_t) SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PANEL_COL_VEC(panel_obj, c, chunk) ((panel_obj).vec[(int)(c)][(int)(chunk)])
|
||||
/* Scalar flat index helper for column-major addressing */
|
||||
#define PANEL_ELEM(panel_obj, T, T_VEC, MINQ, r, c) \
|
||||
((panel_obj).flat[(int)(c) * PANEL_Q(T, T_VEC, MINQ) + (int)(r)])
|
||||
|
||||
/* API macros */
|
||||
#define BUILD_PANEL(arch, element) build_panel_##arch##_##element
|
||||
|
||||
#include "sn_internal.h"
|
||||
#define STORE_PANEL(arch, element) store_panel_##arch##_##element
|
||||
|
||||
#define DECLARE_BUILD_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL BUILD_PANEL(arch, element)( \
|
||||
MAT_PANEL_##arch(element) *restrict panel, \
|
||||
MAT_KERNEL(element) const *const matrix, int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
#define DECLARE_STORE_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL STORE_PANEL(arch, element)(MAT_KERNEL(element) *restrict matrix, \
|
||||
MAT_PANEL_##arch(element) \
|
||||
const *const panel, \
|
||||
int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
|
||||
/* Declarations for AVX float variant */
|
||||
DECLARE_BUILD_PANEL(AVX, float);
|
||||
DECLARE_STORE_PANEL(AVX, float);
|
||||
|
||||
#endif /* SN_MATKERNEL */
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_matkernel.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Define and initialize a global zero kernel aligned to 64 bytes for universal ISA usage */
|
||||
__declspec(align(64)) MAT_KERNEL(uint64_t) SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
__declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_zero_kernel(void)
|
||||
{
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
SN_ZERO_KERNEL.m[r][c] = 0.0;
|
||||
SN_ZERO_KERNEL.m[r][c] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#include "sn_matkernel.h"
|
||||
|
||||
DECLARE_BUILD_PANEL(AVX, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(float) *const k_lt = matrix + (col_index * row_length + row_index);
|
||||
const MAT_KERNEL(float) *const k_rt =
|
||||
has_right ? (matrix + ((col_index + 1) * row_length + row_index)) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom ? (matrix + (col_index * row_length + (row_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
register __m256 col256;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
/* Vector loads: each kernel column is a compact __m128 */
|
||||
top128 = src_top->xmm[kc_col];
|
||||
bot128 = src_bot->xmm[kc_col];
|
||||
|
||||
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
|
||||
col256 = _mm256_set_m128(bot128, top128);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col256;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "sn_matkernel.h"
|
||||
|
||||
DECLARE_BUILD_PANEL(AVX, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(float) *const k_lt = matrix + (col_index * row_length + row_index);
|
||||
const MAT_KERNEL(float) *const k_rt =
|
||||
has_right ? (matrix + ((col_index + 1) * row_length + row_index)) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom ? (matrix + (col_index * row_length + (row_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
register __m256 col256;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
/* Vector loads: each kernel column is a compact __m128 */
|
||||
top128 = src_top->xmm[kc_col];
|
||||
bot128 = src_bot->xmm[kc_col];
|
||||
|
||||
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
|
||||
col256 = _mm256_set_m128(bot128, top128);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col256;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(AVX, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Local dummy kernel to swallow out-of-bounds writes; no init needed */
|
||||
MAT_KERNEL(float) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(float) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (col_index * row_length + row_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + ((col_index + 1) * row_length + row_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + (col_index * row_length + (row_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((col_index + 1) * row_length + (row_index + 1))) :
|
||||
&zero;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
int i = 0;
|
||||
for (; i < Q / 2; i++) {
|
||||
const int kc_col = i; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_rt->xmm[kc_col] = top128;
|
||||
k_rb->xmm[kc_col] = bot128;
|
||||
}
|
||||
for (; i < Q; i++) {
|
||||
const int kc_col = i - 4; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_lt->xmm[kc_col] = top128;
|
||||
k_lb->xmm[kc_col] = bot128;
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,10 @@ void load_intrinsic_sse(sn_intrinsic *context)
|
||||
context->f32_buffer_add = BUF_PROC(float, sse, add);
|
||||
context->f32_panel_fma = KER_PROC(float, sse, fma);
|
||||
context->f32_buffer_fill = BUF_PROC(float, sse, fill);
|
||||
context->f32_kernel_scalar_mul = BUF_PROC(float, sse, scalar_mul);
|
||||
context->f32_kernel_sub = BUF_PROC(float, sse, sub);
|
||||
context->f32_kernel_transpose = KER_PROC(float, sse, transpose);
|
||||
context->variant = BUF_PROC(float, sse, scalar_mul);
|
||||
context->f32_buffer_sub = BUF_PROC(float, sse, sub);
|
||||
context->f32_buffer_transpose = KER_PROC(float, sse, transpose);
|
||||
context->f32_buffer_scalar_mul = BUF_PROC(float, sse, scalar_mul);
|
||||
context->f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
@@ -82,9 +83,10 @@ void load_intrinsic_avx(sn_intrinsic *context)
|
||||
context->f32_buffer_add = BUF_PROC(float, avx, add);
|
||||
context->f32_panel_fma = KER_PROC(float, sse, fma);
|
||||
context->f32_buffer_fill = BUF_PROC(float, avx, fill);
|
||||
context->f32_kernel_scalar_mul = BUF_PROC(float, avx, scalar_mul);
|
||||
context->f32_kernel_sub = BUF_PROC(float, avx, sub);
|
||||
context->f32_kernel_transpose = KER_PROC(float, avx, transpose);
|
||||
context->variant = BUF_PROC(float, avx, scalar_mul);
|
||||
context->f32_buffer_sub = BUF_PROC(float, avx, sub);
|
||||
context->f32_buffer_transpose = KER_PROC(float, avx, transpose);
|
||||
context->f32_buffer_scalar_mul = BUF_PROC(float, avx, scalar_mul);
|
||||
context->f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
@@ -96,8 +98,9 @@ void load_intrinsic_512(sn_intrinsic *context)
|
||||
context->f32_buffer_add = BUF_PROC(float, 512, add);
|
||||
context->f32_panel_fma = KER_PROC(float, sse, fma);
|
||||
context->f32_buffer_fill = BUF_PROC(float, 512, fill);
|
||||
context->f32_kernel_scalar_mul = BUF_PROC(float, 512, scalar_mul);
|
||||
context->f32_kernel_sub = BUF_PROC(float, 512, sub);
|
||||
context->f32_kernel_transpose = KER_PROC(float, 512, transpose);
|
||||
context->variant = BUF_PROC(float, 512, scalar_mul);
|
||||
context->f32_buffer_sub = BUF_PROC(float, 512, sub);
|
||||
context->f32_buffer_transpose = KER_PROC(float, 512, transpose);
|
||||
context->f32_buffer_scalar_mul = BUF_PROC(float, 512, scalar_mul);
|
||||
context->f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using StgSharp.Common.Timing;
|
||||
using StgSharp.HighPerformance;
|
||||
using StgSharp.HighPerformance.Memory;
|
||||
using StgSharp.Internal;
|
||||
using StgSharp.Mathematics.Numeric;
|
||||
using StgSharp.Timing;
|
||||
|
||||
namespace StgSharp
|
||||
{
|
||||
@@ -49,9 +51,9 @@ namespace StgSharp
|
||||
// TestRender();
|
||||
// TestHlsf();
|
||||
|
||||
|
||||
// HlsfStressTest.Run();
|
||||
M128 v = new M128();
|
||||
/**/
|
||||
/*
|
||||
HybridLayerSegregatedFitAllocator hlsf;
|
||||
unchecked {
|
||||
hlsf = new((nuint)(64 * (ulong)10000 * 10000));
|
||||
@@ -84,7 +86,40 @@ namespace StgSharp
|
||||
Console.WriteLine();
|
||||
}
|
||||
/**/
|
||||
|
||||
// --- Logarithmic time sequence test: print seconds at each emitted span ---
|
||||
|
||||
// Configure a simple sequence:
|
||||
// initial slice = 0.5s, total = 5s, growth multiplier = 2, min slice = 0.75s
|
||||
TimeSequence seq =
|
||||
/*
|
||||
TimeSequence.CreateLogarithmic(initialSliceSeconds:0.5,
|
||||
totalSeconds:5.0,
|
||||
growthMultiplier:2.0,
|
||||
minSliceSeconds:0.75);
|
||||
/**/
|
||||
TimeSequence.CreateLinear(5, 1);
|
||||
/**/
|
||||
|
||||
// Bind to default time source provider.
|
||||
TimeSpanProvider provider = new TimeSpanProvider(seq, TimeSpanProvider.DefaultProvider);
|
||||
|
||||
// Print the second mark when a span is emitted.
|
||||
provider.TimeSpanRefreshed += (s, e) => {
|
||||
// CurrentSecond is PreviousFrameTick / Frequency
|
||||
Console.WriteLine($"span @ {provider.CurrentSecond:0.000}s");
|
||||
};
|
||||
|
||||
// Start the time source and wait until sequence ends.
|
||||
TimeSpanProvider.DefaultProvider.StartProvidingTime();
|
||||
|
||||
while (!provider.IsEnded) {
|
||||
provider.WaitNextSpan();
|
||||
}
|
||||
|
||||
TimeSpanProvider.DefaultProvider.StopProvidingTime();
|
||||
|
||||
// end of log-time sequence test
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user