use individual panel define as compute unit, kernel is now storage and loading unit

This commit is contained in:
Youmu Liu
2025-11-12 21:13:00 +08:00
parent bbe69f0384
commit 2dfb4ae86a
33 changed files with 522 additions and 58 deletions
@@ -35,6 +35,7 @@ using StgSharp.Timing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
namespace StgSharp.Controls
@@ -58,6 +59,7 @@ namespace StgSharp.Controls
public ReadOnlySpan<Vec4> TextureBox
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => marker.TextureCoord;
}
+1 -1
View File
@@ -88,7 +88,7 @@ namespace StgSharp.Internal
return;
}
for (int i = begin; i < 255; i++) {
Data[i] = Scaler.Random<byte>();
Data[i] = Scalar.Random<byte>();
}
}
@@ -37,7 +37,7 @@ namespace StgSharp.Mathematics
public static partial class GeometryScaler
{
internal const float DegToRad = 180 / Scaler.Pi;
internal const float DegToRad = 180 / Scalar.Pi;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Cos(Radius r)
@@ -168,7 +168,7 @@ namespace StgSharp.Mathematics
public static implicit operator Degree(Radius r)
{
return new Degree((r._radius * 180) / Scaler.Pi);
return new Degree((r._radius * 180) / Scalar.Pi);
}
}
@@ -46,6 +46,13 @@ namespace StgSharp.Graphics.OpenGL
[FieldOffset(0)] internal int SignedValue;
[FieldOffset(0)] internal uint Value;
public GlHandle()
{
Unsafe.SkipInit(out Value);
Unsafe.SkipInit(out SignedValue);
Unsafe.SkipInit(out this);
}
public static GlHandle Zero
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -0,0 +1,245 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="IMatrixPanel"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.HighPerformance
{
public interface IMatrixPanel<T> : IDisposable where T: unmanaged,INumber<T>
{
static abstract int KernelColumnCount { get; }
static abstract int KernelRowCount { get; }
static abstract int ElementCount { get; }
static abstract nuint Size { get; }
void Dispose();
}
/// <summary>
/// Buffer for SSE targeted matrix panel, size of a panel is 4x4 elements, and no smaller than
/// 16 bytes.
/// </summary>
/// <typeparam name="T">
/// Type of matrix element.
/// </typeparam>
public unsafe struct MatrixPanelSSE<T> : IMatrixPanel<T> where T: unmanaged, INumber<T>
{
private MatrixKernel<T> _buffer;
[Obsolete("Compute kernel should not be created from new(), use Create instead", true)]
public MatrixPanelSSE() { }
public static int KernelColumnCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
int size = sizeof(T);
return size < 4 ? 2 : 1;
}
}
public static int KernelRowCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
int size = sizeof(T);
return size < 4 ? 2 : 1;
}
}
public static int ElementCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
int size = sizeof(T);
return size < 4 ? 64 / size : 16;
}
}
public static unsafe nuint Size
{
get
{
nuint size = (nuint)sizeof(T);
return size < 4 ? 64 : 16 * size;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixPanelSSE<T>* Create()
{
MatrixPanelSSE<T>* kernel = (MatrixPanelSSE<T>*)NativeMemory.AlignedAlloc(Size, 16);
return kernel;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Destroy(MatrixPanelSSE<T>* kernel)
{
NativeMemory.AlignedFree(kernel);
}
public void Dispose()
{
fixed (MatrixPanelSSE<T>* thisPtr = &this) {
NativeMemory.AlignedFree(thisPtr);
}
}
}
/// <summary>
/// Buffer for AVX targeted matrix panel, size of a panel is 4x4 elements, and no smaller than
/// 16 bytes.
/// </summary>
/// <typeparam name="T">
/// Type of matrix element.
/// </typeparam>
public unsafe struct MatrixPanelAVX<T> : IMatrixPanel<T> where T: unmanaged, INumber<T>
{
private M512 _buffer;
[Obsolete("Compute kernel should not be created from new(), use Create instead", true)]
public MatrixPanelAVX() { }
public static unsafe int ElementCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
int size = sizeof(T);
return size < 4 ? 128 / size : 16;
}
}
public static int KernelColumnCount => 2;
public static int KernelRowCount => 2;
public static unsafe nuint Size
{
get
{
nuint size = (nuint)sizeof(T);
return size < 4 ? 128 : 16 * size;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixPanelAVX<T>* Create()
{
MatrixPanelAVX<T>* kernel = (MatrixPanelAVX<T>*)NativeMemory.AlignedAlloc(Size, 16);
return kernel;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Destroy(MatrixPanelAVX<T>* kernel)
{
NativeMemory.AlignedFree(kernel);
}
public void Dispose()
{
fixed (MatrixPanelAVX<T>* thisPtr = &this) {
NativeMemory.AlignedFree(thisPtr);
}
}
}
/// <summary>
/// Buffer for AVX512 targeted matrix panel, size of a panel is 4x4 elements, and no smaller
/// than 16 bytes.
/// </summary>
/// <typeparam name="T">
/// Type of matrix element.
/// </typeparam>
public unsafe struct MatrixComputeKernelAVX512<T> : IMatrixPanel<T> where T: unmanaged, INumber<T>
{
private M512 _buffer;
[Obsolete("Compute kernel should not be created from new(), use Create instead", true)]
public MatrixComputeKernelAVX512() { }
public readonly unsafe int ElementCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
int size = sizeof(T);
return size < 4 ? 128 / size : 16;
}
}
public static int KernelColumnCount { get; }
public static int KernelRowCount { get; }
public static unsafe nuint Size
{
get
{
nuint size = (nuint)sizeof(T);
return size < 4 ? 128 : 16 * size;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixComputeKernelAVX512<T>* Create()
{
MatrixComputeKernelAVX512<T>* kernel = (MatrixComputeKernelAVX512<T>*)NativeMemory.AlignedAlloc(Size, 16);
return kernel;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Destroy(MatrixComputeKernelAVX512<T>* kernel)
{
NativeMemory.AlignedFree(kernel);
}
public void Dispose()
{
fixed (MatrixComputeKernelAVX512<T>* thisPtr = &this) {
NativeMemory.AlignedFree(thisPtr);
}
}
}
}
@@ -25,6 +25,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -185,7 +185,7 @@ namespace StgSharp.Mathematics.Graphic
far = distance + depthRange.back,
offsetX = offset.X,
offsetY = offset.Y,
width = Scaler.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2),
width = Scalar.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2),
height = width * size.Y / size.X;
_projection.column[0].X = 2 * near / width;
@@ -34,13 +34,13 @@ namespace StgSharp.Mathematics.Graphic
public static float GetAngle(Vec2 vec1, Vec2 vec2)
{
return Scaler.ACos(
return Scalar.ACos(
1 / (vec1.GetLength() * vec2.GetLength()));
}
public static float GetAngle(Vec3 vec1, Vec3 vec2)
{
return Scaler.ACos((vec1 * vec2) / (vec1.GetLength() * vec2.GetLength()));
return Scalar.ACos((vec1 * vec2) / (vec1.GetLength() * vec2.GetLength()));
}
}
@@ -34,12 +34,12 @@ namespace StgSharp.Mathematics.Graphic
public static float GetLength(this Vec3 vec)
{
return Scaler.Sqrt(vec.Dot(vec));
return Scalar.Sqrt(vec.Dot(vec));
}
public static float GetLength(this Vec2 vec)
{
return Scaler.Sqrt(vec.Dot(vec));
return Scalar.Sqrt(vec.Dot(vec));
}
}
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+1 -1
View File
@@ -29,7 +29,7 @@ using System;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
private const float
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -31,7 +31,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -33,7 +33,7 @@ using System.Threading.Tasks;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
public static float MaxOf(params float[] stream)
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+2 -2
View File
@@ -32,7 +32,7 @@ namespace StgSharp.Mathematics
{
public unsafe delegate float ScalarCalcHandler(float* x);
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
private const uint MEM_COMMIT = 0x1000;
@@ -40,7 +40,7 @@ namespace StgSharp.Mathematics
private const uint MEM_RESERVE = 0x2000;
private const uint PAGE_EXECUTE_READWRITE = 0x40;
static Scaler() { }
static Scalar() { }
[DllImport("Kernel32.dll", EntryPoint = "VirtualAlloc")]
private static extern IntPtr VirtualAlloc(IntPtr address, int size, uint allocType, uint protect);
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
public const float E = 2.718281828f;
@@ -29,7 +29,7 @@ using System;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
private static readonly uint[] factorialResult = [
+1 -1
View File
@@ -29,7 +29,7 @@ using System;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
private static readonly float[] logArray = {
+2 -2
View File
@@ -29,7 +29,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -81,7 +81,7 @@ namespace StgSharp.Mathematics
return 0;
}
z = Scaler.Log(x) * y;
z = Scalar.Log(x) * y;
bool sign = false;
if (z < 0)
+4 -4
View File
@@ -38,7 +38,7 @@ using System.Text;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
private static byte[] randomSeed;
@@ -61,9 +61,9 @@ namespace StgSharp.Mathematics
{
float seed = currentSeed;
float sample = Scaler.Pow(Scaler.SeedSqrt(seed), 2);
float sample = Scalar.Pow(Scalar.SeedSqrt(seed), 2);
float sample2 = (sample - seed) / seed;
sample2 = Scaler.Abs(sample2);
sample2 = Scalar.Abs(sample2);
if (sample == 1) {
sample = sample2;
@@ -76,7 +76,7 @@ namespace StgSharp.Mathematics
if (result == 0)
{
currentSeed = sample2 + 0.1f;
result = Scaler.LowProceisionRandom();
result = Scalar.LowProceisionRandom();
}
return result;
}
+1 -1
View File
@@ -34,7 +34,7 @@ using System.Threading.Tasks;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scaler
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+1 -1
View File
@@ -31,7 +31,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
public const float Pi = 3.1415926f;
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
public static unsafe float SeedSqrt(float x)
+1 -1
View File
@@ -30,7 +30,7 @@ using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scaler
public static partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+1 -1
View File
@@ -115,7 +115,7 @@ namespace StgSharp.Stg
public void Init(Radius angleStride, string name)
{
primeArgs = new ViewPort(
1, (int)((new Radius(Scaler.Pi)) / angleStride), name, IntPtr.Zero);
1, (int)((new Radius(Scalar.Pi)) / angleStride), name, IntPtr.Zero);
PlatformSpecifiedInitialize();
CustomizeInit();
+4 -12
View File
@@ -36,7 +36,6 @@ namespace StgSharp.Timing
{
private float _beginning, _ending;
private Func<float, float> _timeRelatedCalculation;
private TimeSpanProvider _timeProvider;
internal TimeFunction() { }
@@ -44,7 +43,7 @@ namespace StgSharp.Timing
public TimeFunction(TimeSpanProvider timeSpanProvider, Func<float, float> timeRelatedCalculation, float range)
{
_timeProvider = timeSpanProvider;
_timeRelatedCalculation = timeRelatedCalculation;
TimeRelatedCalculation = timeRelatedCalculation;
if (timeSpanProvider == null) {
return;
}
@@ -58,14 +57,7 @@ namespace StgSharp.Timing
get => _timeProvider.CurrentSecond > _ending;
}
public Func<float, float> TimeRelatedCalculation
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _timeRelatedCalculation;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => _timeRelatedCalculation = value;
}
public Func<float, float> TimeRelatedCalculation { get; set; }
public static TimeFunction One
{
@@ -86,7 +78,7 @@ namespace StgSharp.Timing
if (_timeProvider.CurrentSecond < _ending) {
return 0;
}
return _timeRelatedCalculation(_timeProvider.CurrentSecond - _beginning);
return TimeRelatedCalculation(_timeProvider.CurrentSecond - _beginning);
}
public static TimeFunction Proportional(TimeSpanProvider time, float begin, float range)
@@ -115,7 +107,7 @@ namespace StgSharp.Timing
{
float range = _ending - _beginning;
return new TimeFunction(
_timeProvider, p => _timeRelatedCalculation(range - p), range);
_timeProvider, p => TimeRelatedCalculation(range - p), range);
}
}
+93
View File
@@ -0,0 +1,93 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="TimeSequence"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Common.Timing
{
public abstract class TimeSequence
{
public ulong BeginningTick { get; protected set; }
public ulong EndingTick { get; protected set; }
public ulong FrameLength { get; protected set; }
public static TimeSequence CreateLinear(ulong timeout, ulong length)
{
return new LinearTimeSequence(timeout, timeout + length, length);
}
public abstract bool IsNextFrameReady(ulong currentTick);
}
internal sealed class LogTimeSequence : TimeSequence
{
private float _rate ;
public LogTimeSequence(ulong beginningTick, ulong endingTick, ulong tickPerDecade)
{
BeginningTick = beginningTick;
EndingTick = endingTick;
_rate = Scalar.Pow(10, 1 / tickPerDecade);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool IsNextFrameReady(ulong currentTick)
{
return (ulong)Math.Log(currentTick - BeginningTick + 1) >= FrameLength;
}
}
internal sealed class LinearTimeSequence : TimeSequence
{
public LinearTimeSequence(ulong beginningTick, ulong endingTick, ulong tickPerFrame)
{
BeginningTick = beginningTick;
EndingTick = endingTick;
FrameLength = tickPerFrame;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool IsNextFrameReady(ulong currentTick)
{
return currentTick - BeginningTick >= FrameLength;
}
}
}
+3 -3
View File
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="StepLine"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -85,7 +85,7 @@ namespace StgSharp.Model.Step
float dx = x2 - x1;
float dy = y2 - y1;
float dz = z2 - z1;
float length = Scaler.Sqrt(dx * dx + dy * dy + dz * dz);
float length = Scalar.Sqrt(dx * dx + dy * dy + dz * dz);
float dxn = dx / length;
float dyn = dy / length;
float dzn = dz / length;
+1
View File
@@ -39,6 +39,7 @@ typedef union scalar_pack {
typedef void(SN_DECL *VECTORNORMALIZEPROC)(__m128 *source, __m128 *target);
typedef void(SN_DECL *DOTPROC)(void *transpose, __m128 *vector, __m128 *ans);
typedef void(SN_DECL *PANEL_PROC_AS)(MAT_PANEL_SSE(int));
typedef void(SN_DECL *MAT_PROC_AS)(mat_kernel *ans, scalar_pack *scalar);
typedef void(SN_DECL *MAT_PROC_LA)(mat_kernel *left, mat_kernel *ans);
typedef void(SN_DECL *MAT_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans);
+102 -6
View File
@@ -8,12 +8,12 @@
#include <immintrin.h>
#define MAT_KERNEL(T) \
union { \
__m128 xmm[XMMCOUNT(T)]; \
__m256 ymm[YMMCOUNT(T)]; \
__m512 zmm[ZMMCOUNT(T)]; \
T m[4][4]; \
#define MAT_KERNEL(T) \
union { \
__m128 xmm[XMMCOUNT(T) / 4]; \
__m256 ymm[YMMCOUNT(T) / 4]; \
__m512 zmm[ZMMCOUNT(T) / 4]; \
T m[4][4]; \
}
#define VEC(T) \
@@ -25,3 +25,99 @@
}
#endif
#include <stddef.h>
#include <stdint.h>
/* align decoration */
#if __cplusplus && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
#define ML_ALIGNAS(n) _Alignas(n)
#elif defined(_MSC_VER)
#define ML_ALIGNAS(n) __declspec(align(n))
#else
#define ML_ALIGNAS(n) __attribute__((aligned(n)))
#endif
/* Round up to the alignment boundary in bytes */
#ifndef ML_ALIGN_UP
#define ML_ALIGN_UP(x, a) (((size_t)(x) + ((size_t)(a) - 1)) & ~((size_t)(a) - 1))
#endif
/* Vector register width in bytes */
#define ML_BYTES_XMM 16u
#define ML_BYTES_YMM 32u
#define ML_BYTES_ZMM 64u
/* Compute the aligned leading-direction element stride (LEp) */
#define ML_PANEL_STRIDE_ELEMS(T, LE, ALIGN) \
(ML_ALIGN_UP((size_t)(LE) * sizeof(T), (size_t)(ALIGN)) / sizeof(T))
/* Total element count and total byte count */
#define ML_PANEL_TOT_ELEMS(T, LE, MINOR, ALIGN) \
((size_t)ML_PANEL_STRIDE_ELEMS(T, (LE), (ALIGN)) * (size_t)(MINOR))
#define ML_TOT_BYTES(T, ELEMS) ((size_t)(ELEMS) * sizeof(T))
/* Number of SIMD view slots (ceil by total bytes) */
#define ML_XMM_COUNT(TOT_BYTES) (((size_t)(TOT_BYTES) + ML_BYTES_XMM - 1) / ML_BYTES_XMM)
#define ML_YMM_COUNT(TOT_BYTES) (((size_t)(TOT_BYTES) + ML_BYTES_YMM - 1) / ML_BYTES_YMM)
#define ML_ZMM_COUNT(TOT_BYTES) (((size_t)(TOT_BYTES) + ML_BYTES_ZMM - 1) / ML_BYTES_ZMM)
/* ========== Unified "panel" union (no enum/descriptor fields) ==========
Usage:
MAT_PANEL(float, 8, 32, 32) P; // LE=8, MINOR=32, aligned to 32 bytes
Views:
P.xmm[] / P.ymm[] / P.zmm[] // raw SIMD blocks
P.blk[MINOR][LEp] // 2D scalar view (includes padding for alignment)
P.flat[MINOR*LEp] // flat array
Notes:
- LE/MINOR/ALIGN must be compile-time constants
- LEp = ML_PANEL_STRIDE_ELEMS(T, LE, ALIGN)
- Layout/semantics defined by the calling convention (e.g. blk[k][r] is element r of block k)
*/
#define MAT_PANEL(T, LE, MINOR, ALIGN) \
ML_ALIGNAS(ALIGN) union { \
/* Raw SIMD view: cast to __m256/__m512d inside the micro-kernel on demand */ \
__m128i xmm[ML_XMM_COUNT( \
ML_TOT_BYTES(T, ML_PANEL_TOT_ELEMS(T, (LE), (MINOR), (ALIGN))))]; \
__m256i ymm[ML_YMM_COUNT( \
ML_TOT_BYTES(T, ML_PANEL_TOT_ELEMS(T, (LE), (MINOR), (ALIGN))))]; \
__m512i zmm[ML_ZMM_COUNT( \
ML_TOT_BYTES(T, ML_PANEL_TOT_ELEMS(T, (LE), (MINOR), (ALIGN))))]; \
/* Scalar 2D view: minor �� LEp (LE dimension contains alignment padding) */ \
T blk[(MINOR)][ML_PANEL_STRIDE_ELEMS(T, (LE), (ALIGN))]; \
/* Flat view */ \
T flat[ML_PANEL_TOT_ELEMS(T, (LE), (MINOR), (ALIGN))]; \
}
/* ---------- SSE preset ---------- */
#undef PANEL_LE
#undef PANEL_MINOR
#undef PANEL_ALIGN
#define PANEL_LE 4
#define PANEL_MINOR 32
#define PANEL_ALIGN 16
/* ======== SSE preset ========
4 x 32, 16B aligned
*/
#define MAT_PANEL_SSE(T) MAT_PANEL(T, PANEL_LE, PANEL_MINOR, PANEL_ALIGN)
/* ---------- AVX2 preset ---------- */
#undef PANEL_LE
#undef PANEL_MINOR
#undef PANEL_ALIGN
#define PANEL_LE 8
#define PANEL_MINOR 64
#define PANEL_ALIGN 32
#define MAT_PANEL_AVX(T) MAT_PANEL(T, PANEL_LE, PANEL_MINOR, PANEL_ALIGN) /* 8 x 64, 32B aligned */
/* ---------- AVX-512 preset ---------- */
#undef PANEL_LE
#undef PANEL_MINOR
#undef PANEL_ALIGN
#define PANEL_LE 16
#define PANEL_MINOR 64
#define PANEL_ALIGN 64
#define MAT_PANEL_512(T) \
MAT_PANEL(T, PANEL_LE, PANEL_MINOR, PANEL_ALIGN); /* 16 x 64, 64B aligned */
+30 -3
View File
@@ -1,5 +1,9 @@
#include "sn_intrinsic.h"
INTERNAL void SN_DECL f32_fma_sse(MAT_PANEL_SSE(int) * left)
{
}
// ans = left * right + ans
// right is not transposed
INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left,
@@ -41,9 +45,32 @@ INTERNAL void SN_DECL f32_fma_avx(MAT_KERNEL(float) const *restrict left,
MAT_KERNEL(float) const *restrict right,
MAT_KERNEL(float) *restrict ans)
{
/*
* to be implemented
*/
register __m256 source0 = _mm256_load_ps(&left->ymm[0]);
register __m256 source1 = _mm256_load_ps(&left->ymm[1]);
register __m256 ans0 = _mm256_load_ps(&ans->ymm[0]);
register __m256 ans1 = _mm256_load_ps(&ans->ymm[1]);
register __m128 bs0, bs1;
register __m256 broadcast;
for (size_t i = 0; i < 4; i++) {
bs0 = _mm_load_ps(&right->xmm[i]);
__m128 lo = _mm_shuffle_ps(bs0, bs0, 0x00);
__m128 hi = _mm_shuffle_ps(bs0, bs0, 0x55);
broadcast = _mm256_castps128_ps256(lo);
broadcast = _mm256_insertf128_ps(broadcast, bs0, 1);
ans0 = _mm256_add_ps(ans0, _mm256_mul_ps(source0, broadcast));
lo = _mm_shuffle_ps(bs0, bs0, 0xAA);
hi = _mm_shuffle_ps(bs0, bs0, 0xFF);
broadcast = _mm256_castps128_ps256(lo);
broadcast = _mm256_insertf128_ps(broadcast, bs0, 1);
ans1 = _mm256_add_ps(ans1, _mm256_mul_ps(source1, broadcast));
}
_mm256_store_ps(&ans->ymm[0], ans0);
_mm256_store_ps(&ans->ymm[1], ans1);
}
// ans = left * right + ans
+4 -4
View File
@@ -200,7 +200,7 @@ namespace StgSharp
{
rotation = provider.SpanLengthLowPrecession;
float angle = provider.CurrentSecond * 2;
return (new Vec3(Scaler.Cos(angle), Scaler.Sin(angle),
return (new Vec3(Scalar.Cos(angle), Scalar.Sin(angle),
0)) * provider.SpanLengthLowPrecession;
}
@@ -214,16 +214,16 @@ namespace StgSharp
buffer = new PlainInstancingBuffer<ParticleOnPlain>();
for (int i = 0; i < 10; i++)
{
float ai = Scaler.Abs(i - 5.0f);
float ai = Scalar.Abs(i - 5.0f);
for (int t = 0; t < 10; t++)
{
float at = Scaler.Abs(t - 5.0f);
float at = Scalar.Abs(t - 5.0f);
ParticleOnPlain p = new ParticleOnPlain(buffer);
((IInstancing)p).Coord = new Vec3(
(((-5) + i) * 0.2f) + 0.1f, (((-5) + t) * 0.2f) + 0.1f, 0);
((IInstancing)p).Scale =
Scaler.MinOf(i, t) * 0.15f;
Scalar.MinOf(i, t) * 0.15f;
((IInstancing)p).Motion = new GeometryMotion(
true, TimeProvider, DefaultRotation);
}