diff --git a/Misaki.HighPerformance.Mathematics.SPMD/ISPMDLane.cs b/Misaki.HighPerformance.Mathematics.SPMD/ISPMDLane.cs index ce97c84..e8c2ecf 100644 --- a/Misaki.HighPerformance.Mathematics.SPMD/ISPMDLane.cs +++ b/Misaki.HighPerformance.Mathematics.SPMD/ISPMDLane.cs @@ -597,13 +597,22 @@ public unsafe interface ISPMDLane : ISPMDLane, IEquatable static abstract TSelf Rsqrt(TSelf value); /// - /// Horizontally reduces the lane value by adding all lanes together, returning a single-lane result. + /// Reduces the lane value to a single scalar by adding all lanes together. /// - /// - /// - /// + /// The lane value to reduce. + /// The reduced scalar value. static abstract TNumber ReduceAdd(TSelf value); + /// + /// Reduces the lane value to a single scalar by finding the maximum element. + /// + /// The lane value to reduce. + /// The reduced scalar value. static abstract TNumber ReduceMax(TSelf value); + /// + /// Reduces the lane value to a single scalar by finding the minimum element. + /// + /// The lane value to reduce. + /// The reduced scalar value. static abstract TNumber ReduceMin(TSelf value); /// diff --git a/Misaki.HighPerformance.Mathematics.SPMD/Misaki.HighPerformance.Mathematics.SPMD.csproj b/Misaki.HighPerformance.Mathematics.SPMD/Misaki.HighPerformance.Mathematics.SPMD.csproj index 86ac811..3431fed 100644 --- a/Misaki.HighPerformance.Mathematics.SPMD/Misaki.HighPerformance.Mathematics.SPMD.csproj +++ b/Misaki.HighPerformance.Mathematics.SPMD/Misaki.HighPerformance.Mathematics.SPMD.csproj @@ -7,7 +7,7 @@ true true Misaki - 1.3.2 + 1.3.3 $(AssemblyVersion) https://git.personalnas.com/Misaki/Misaki.HighPerformance.git https://git.personalnas.com/Misaki/Misaki.HighPerformance.git diff --git a/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.gen.cs b/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.gen.cs index a9ad531..9c031d1 100644 --- a/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.gen.cs +++ b/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.gen.cs @@ -17,7 +17,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Create(in TLane x, in TLane y) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -29,7 +29,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 CreateVector2(in TLane value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -41,7 +41,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 LoadVector2(TNumber* pSrc) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var width = TLane.LaneWidth; @@ -64,7 +64,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 LoadVector2(ref TNumber src) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector2((TNumber*)Unsafe.AsPointer(ref src)); @@ -72,7 +72,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Load(TNumber* px, TNumber* py) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -84,7 +84,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Load(ref TNumber x, ref TNumber y) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -97,81 +97,101 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(TNumber* pData, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 2]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; + + px[i] = pData[scalarIdx + 0 * scale]; + py[i] = pData[scalarIdx + 1 * scale]; } return new Vector2 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), + x = x, + y = y, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(TNumber* pData, int* pIndices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 2]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + for (var i = 0; i < TLane.LaneWidth; i++) { - var scalarIdx = pIndices[i]; - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; + var scalerIdx = pIndices[i]; + + px[i] = pData[scalerIdx + 0 * scale]; + py[i] = pData[scalerIdx + 1 * scale]; } return new Vector2 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), + x = x, + y = y, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(ref TNumber baseAddress, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 2]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); } return new Vector2 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), + x = x, + y = y, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(ref TNumber baseAddress, ref int baseIndex, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 2]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = Unsafe.Add(ref baseIndex, i); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); } return new Vector2 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), + x = x, + y = y, }; } @@ -180,7 +200,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Abs(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -192,7 +212,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Dot(in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y; @@ -200,7 +220,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Sin(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -212,7 +232,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Cos(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -224,7 +244,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector2 vector, out Vector2 sin, out Vector2 cos) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); @@ -233,7 +253,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Sqrt(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -245,7 +265,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Tan(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -257,7 +277,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Asin(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -269,7 +289,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Acos(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -281,7 +301,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Atan(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -293,7 +313,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Atan2(in Vector2 x, in Vector2 y) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -305,7 +325,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Rsqrt(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -317,7 +337,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Normalize(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); @@ -325,7 +345,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Reflect(in Vector2 incident, in Vector2 normal) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); @@ -334,7 +354,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Min(in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -346,7 +366,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -358,7 +378,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(in Vector2 value, in Vector2 min, in Vector2 max) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); @@ -366,7 +386,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Saturate(in Vector2 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector2(TLane.Zero), CreateVector2(TLane.One)); @@ -374,7 +394,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Lerp(in Vector2 a, in Vector2 b, TLane t) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; @@ -382,7 +402,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); @@ -390,7 +410,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector2 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); @@ -398,7 +418,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -407,7 +427,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -416,7 +436,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Step(in Vector2 edge, in Vector2 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector2.One, Vector2.Zero); @@ -424,7 +444,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Smoothstep(Vector2 xMin, Vector2 xMax, Vector2 x) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var t = Saturate((x - xMin) / (xMax - xMin)); @@ -436,7 +456,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Select(TLane condition, in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -448,7 +468,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Select(Vector2 condition, in Vector2 a, in Vector2 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 @@ -466,7 +486,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Create(in TLane x, in TLane y, in TLane z) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -479,7 +499,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 CreateVector3(in TLane value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -492,7 +512,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 LoadVector3(TNumber* pSrc) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var width = TLane.LaneWidth; @@ -518,7 +538,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 LoadVector3(ref TNumber src) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector3((TNumber*)Unsafe.AsPointer(ref src)); @@ -526,7 +546,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Load(TNumber* px, TNumber* py, TNumber* pz) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -539,7 +559,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Load(ref TNumber x, ref TNumber y, ref TNumber z) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -553,89 +573,117 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(TNumber* pData, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 3]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; - buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale]; + + px[i] = pData[scalarIdx + 0 * scale]; + py[i] = pData[scalarIdx + 1 * scale]; + pz[i] = pData[scalarIdx + 2 * scale]; } return new Vector3 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), + x = x, + y = y, + z = z, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(TNumber* pData, int* pIndices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 3]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + for (var i = 0; i < TLane.LaneWidth; i++) { - var scalarIdx = pIndices[i]; - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; - buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale]; + var scalerIdx = pIndices[i]; + + px[i] = pData[scalerIdx + 0 * scale]; + py[i] = pData[scalerIdx + 1 * scale]; + pz[i] = pData[scalerIdx + 2 * scale]; } return new Vector3 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), + x = x, + y = y, + z = z, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(ref TNumber baseAddress, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 3]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); - buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); } return new Vector3 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), + x = x, + y = y, + z = z, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(ref TNumber baseAddress, ref int baseIndex, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 3]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = Unsafe.Add(ref baseIndex, i); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); - buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); } return new Vector3 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), + x = x, + y = y, + z = z, }; } @@ -644,7 +692,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Abs(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -657,7 +705,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Dot(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y + a.z * b.z; @@ -665,7 +713,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Sin(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -678,7 +726,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cos(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -691,7 +739,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector3 vector, out Vector3 sin, out Vector3 cos) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); @@ -701,7 +749,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Sqrt(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -714,7 +762,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Tan(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -727,7 +775,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Asin(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -740,7 +788,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Acos(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -753,7 +801,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Atan(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -766,7 +814,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Atan2(in Vector3 x, in Vector3 y) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -779,7 +827,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Rsqrt(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -792,7 +840,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Normalize(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); @@ -800,7 +848,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Reflect(in Vector3 incident, in Vector3 normal) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); @@ -809,7 +857,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Min(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -822,7 +870,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Max(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -835,7 +883,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Clamp(in Vector3 value, in Vector3 min, in Vector3 max) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); @@ -843,7 +891,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Saturate(in Vector3 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector3(TLane.Zero), CreateVector3(TLane.One)); @@ -851,7 +899,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Lerp(in Vector3 a, in Vector3 b, TLane t) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; @@ -859,7 +907,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); @@ -867,7 +915,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector3 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); @@ -875,7 +923,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -884,7 +932,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -893,7 +941,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Step(in Vector3 edge, in Vector3 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector3.One, Vector3.Zero); @@ -901,7 +949,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Smoothstep(Vector3 xMin, Vector3 xMax, Vector3 x) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var t = Saturate((x - xMin) / (xMax - xMin)); @@ -913,7 +961,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Select(TLane condition, in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -926,7 +974,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Select(Vector3 condition, in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 @@ -945,7 +993,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Create(in TLane x, in TLane y, in TLane z, in TLane w) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -959,7 +1007,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 CreateVector4(in TLane value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -973,7 +1021,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LoadVector4(TNumber* pSrc) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var width = TLane.LaneWidth; @@ -1002,7 +1050,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LoadVector4(ref TNumber src) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector4((TNumber*)Unsafe.AsPointer(ref src)); @@ -1010,7 +1058,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Load(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1024,7 +1072,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Load(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1039,97 +1087,133 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(TNumber* pData, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 4]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + Unsafe.SkipInit(out TLane w); + var pw = (TNumber*)&w; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; - buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale]; - buffer[3 * TLane.LaneWidth + i] = pData[scalarIdx + 3 * scale]; + + px[i] = pData[scalarIdx + 0 * scale]; + py[i] = pData[scalarIdx + 1 * scale]; + pz[i] = pData[scalarIdx + 2 * scale]; + pw[i] = pData[scalarIdx + 3 * scale]; } return new Vector4 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), - w = TLane.Load(buffer + 3 * TLane.LaneWidth), + x = x, + y = y, + z = z, + w = w, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(TNumber* pData, int* pIndices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 4]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + Unsafe.SkipInit(out TLane w); + var pw = (TNumber*)&w; + for (var i = 0; i < TLane.LaneWidth; i++) { - var scalarIdx = pIndices[i]; - buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale]; - buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale]; - buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale]; - buffer[3 * TLane.LaneWidth + i] = pData[scalarIdx + 3 * scale]; + var scalerIdx = pIndices[i]; + + px[i] = pData[scalerIdx + 0 * scale]; + py[i] = pData[scalerIdx + 1 * scale]; + pz[i] = pData[scalerIdx + 2 * scale]; + pw[i] = pData[scalerIdx + 3 * scale]; } return new Vector4 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), - w = TLane.Load(buffer + 3 * TLane.LaneWidth), + x = x, + y = y, + z = z, + w = w, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(ref TNumber baseAddress, TLane indices, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 4]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + Unsafe.SkipInit(out TLane w); + var pw = (TNumber*)&w; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); - buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); - buffer[3 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); + pw[i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale); } return new Vector4 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), - w = TLane.Load(buffer + 3 * TLane.LaneWidth), + x = x, + y = y, + z = z, + w = w, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(ref TNumber baseAddress, ref int baseIndex, int scale) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { - var buffer = stackalloc TNumber[TLane.LaneWidth * 4]; + Unsafe.SkipInit(out TLane x); + var px = (TNumber*)&x; + Unsafe.SkipInit(out TLane y); + var py = (TNumber*)&y; + Unsafe.SkipInit(out TLane z); + var pz = (TNumber*)&z; + Unsafe.SkipInit(out TLane w); + var pw = (TNumber*)&w; + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = Unsafe.Add(ref baseIndex, i); - buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); - buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); - buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); - buffer[3 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale); + + px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale); + py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale); + pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale); + pw[i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale); } return new Vector4 { - x = TLane.Load(buffer + 0 * TLane.LaneWidth), - y = TLane.Load(buffer + 1 * TLane.LaneWidth), - z = TLane.Load(buffer + 2 * TLane.LaneWidth), - w = TLane.Load(buffer + 3 * TLane.LaneWidth), + x = x, + y = y, + z = z, + w = w, }; } @@ -1138,7 +1222,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Abs(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1152,7 +1236,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Dot(in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; @@ -1160,7 +1244,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Sin(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1174,7 +1258,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Cos(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1188,7 +1272,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector4 vector, out Vector4 sin, out Vector4 cos) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); @@ -1199,7 +1283,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Sqrt(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1213,7 +1297,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Tan(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1227,7 +1311,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Asin(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1241,7 +1325,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Acos(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1255,7 +1339,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Atan(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1269,7 +1353,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Atan2(in Vector4 x, in Vector4 y) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1283,7 +1367,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Rsqrt(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1297,7 +1381,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Normalize(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); @@ -1305,7 +1389,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Reflect(in Vector4 incident, in Vector4 normal) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); @@ -1314,7 +1398,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Min(in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1328,7 +1412,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Max(in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1342,7 +1426,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Clamp(in Vector4 value, in Vector4 min, in Vector4 max) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); @@ -1350,7 +1434,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Saturate(in Vector4 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector4(TLane.Zero), CreateVector4(TLane.One)); @@ -1358,7 +1442,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Lerp(in Vector4 a, in Vector4 b, TLane t) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; @@ -1366,7 +1450,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); @@ -1374,7 +1458,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector4 vector) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); @@ -1382,7 +1466,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -1391,7 +1475,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; @@ -1400,7 +1484,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Step(in Vector4 edge, in Vector4 value) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector4.One, Vector4.Zero); @@ -1408,7 +1492,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Smoothstep(Vector4 xMin, Vector4 xMax, Vector4 x) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var t = Saturate((x - xMin) / (xMax - xMin)); @@ -1420,7 +1504,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Select(TLane condition, in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1434,7 +1518,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Select(Vector4 condition, in Vector4 a, in Vector4 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 @@ -1453,7 +1537,7 @@ public static unsafe partial class MathV [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cross(in Vector3 a, in Vector3 b) - where TLane : ISPMDLane + where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 diff --git a/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.tt b/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.tt index cf01449..0a09272 100644 --- a/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.tt +++ b/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.tt @@ -21,7 +21,7 @@ const string GenericParameters = $"{TLane}, {TNumber}"; var dimensions = new int[] { 2, 3, 4 }; var components = new char[] { 'x', 'y', 'z', 'w' }; -var TLaneRestrictions = $@"where {TLane} : ISPMDLane<{TLane}, {TNumber}>"; +var TLaneRestrictions = $@"where {TLane} : unmanaged, ISPMDLane<{TLane}, {TNumber}>"; var TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>"; #> @@ -126,19 +126,24 @@ public static unsafe partial class MathV <#= TLaneRestrictions #> <#= TNumberRestrictions #> { - var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>]; +<# for (int i = 0; i < dimension; i++) { #> + Unsafe.SkipInit(out TLane <#= components[i] #>); + var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>; +<# } #> + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); + <# for (int i = 0; i < dimension; i++) { #> - buffer[<#= i #> * TLane.LaneWidth + i] = pData[scalarIdx + <#= i #> * scale]; + p<#= components[i] #>[i] = pData[scalarIdx + <#= i #> * scale]; <# } #> } - return new <#= vectorType #> + return new Vector<#= dimension #> { <# for (int i = 0; i < dimension; i++) { #> - <#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth), + <#= components[i] #> = <#= components[i] #>, <# } #> }; } @@ -148,19 +153,24 @@ public static unsafe partial class MathV <#= TLaneRestrictions #> <#= TNumberRestrictions #> { - var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>]; +<# for (int i = 0; i < dimension; i++) { #> + Unsafe.SkipInit(out TLane <#= components[i] #>); + var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>; +<# } #> + for (var i = 0; i < TLane.LaneWidth; i++) { - var scalarIdx = pIndices[i]; + var scalerIdx = pIndices[i]; + <# for (int i = 0; i < dimension; i++) { #> - buffer[<#= i #> * TLane.LaneWidth + i] = pData[scalarIdx + <#= i #> * scale]; + p<#= components[i] #>[i] = pData[scalerIdx + <#= i #> * scale]; <# } #> } - return new <#= vectorType #> + return new Vector<#= dimension #> { <# for (int i = 0; i < dimension; i++) { #> - <#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth), + <#= components[i] #> = <#= components[i] #>, <# } #> }; } @@ -170,19 +180,24 @@ public static unsafe partial class MathV <#= TLaneRestrictions #> <#= TNumberRestrictions #> { - var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>]; +<# for (int i = 0; i < dimension; i++) { #> + Unsafe.SkipInit(out TLane <#= components[i] #>); + var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>; +<# } #> + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = int.CreateTruncating(indices[i]); + <# for (int i = 0; i < dimension; i++) { #> - buffer[<#= i #> * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale); + p<#= components[i] #>[i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale); <# } #> } - return new <#= vectorType #> + return new Vector<#= dimension #> { <# for (int i = 0; i < dimension; i++) { #> - <#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth), + <#= components[i] #> = <#= components[i] #>, <# } #> }; } @@ -192,19 +207,24 @@ public static unsafe partial class MathV <#= TLaneRestrictions #> <#= TNumberRestrictions #> { - var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>]; +<# for (int i = 0; i < dimension; i++) { #> + Unsafe.SkipInit(out TLane <#= components[i] #>); + var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>; +<# } #> + for (var i = 0; i < TLane.LaneWidth; i++) { var scalarIdx = Unsafe.Add(ref baseIndex, i); + <# for (int i = 0; i < dimension; i++) { #> - buffer[<#= i #> * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale); + p<#= components[i] #>[i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale); <# } #> } - return new <#= vectorType #> + return new Vector<#= dimension #> { <# for (int i = 0; i < dimension; i++) { #> - <#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth), + <#= components[i] #> = <#= components[i] #>, <# } #> }; } diff --git a/Misaki.HighPerformance.Mathematics.SPMD/WideLane.cs b/Misaki.HighPerformance.Mathematics.SPMD/WideLane.cs index 108e78d..bdaa112 100644 --- a/Misaki.HighPerformance.Mathematics.SPMD/WideLane.cs +++ b/Misaki.HighPerformance.Mathematics.SPMD/WideLane.cs @@ -207,49 +207,69 @@ public readonly unsafe partial struct WideLane : ISPMDLane Gather(TNumber* pData, WideLane indices, int scale) { - var buffer = stackalloc TNumber[LaneWidth]; - for (var i = 0; i < LaneWidth; i++) + Unsafe.SkipInit(out Vector result); + + var pResult = (TNumber*)&result; + var pIndices = (TNumber*)&indices; + + var count = Vector.Count; + for (var i = 0; i < count; i++) { - buffer[i] = pData[int.CreateTruncating(indices[i]) * scale / sizeof(TNumber)]; + var idx = int.CreateTruncating(pIndices[i]); + pResult[i] = pData[idx * scale / sizeof(TNumber)]; } - return new WideLane(Vector.Load(buffer)); + return new WideLane(result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static WideLane Gather(TNumber* pData, int* pIndices, int scale) { - var buffer = stackalloc TNumber[LaneWidth]; - for (var i = 0; i < LaneWidth; i++) + Unsafe.SkipInit(out Vector result); + + var pResult = (TNumber*)&result; + + var count = Vector.Count; + for (var i = 0; i < count; i++) { - buffer[i] = pData[pIndices[i] * scale / sizeof(TNumber)]; + pResult[i] = pData[pIndices[i] * scale / sizeof(TNumber)]; } - return new WideLane(Vector.Load(buffer)); + return new WideLane(result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static WideLane Gather(ref TNumber baseAddress, WideLane indices, int scale) { - var buffer = stackalloc TNumber[LaneWidth]; - for (var i = 0; i < LaneWidth; i++) + Unsafe.SkipInit(out Vector result); + + var pResult = (TNumber*)&result; + var pIndices = (TNumber*)&indices; + + var count = Vector.Count; + for (var i = 0; i < count; i++) { - buffer[i] = Unsafe.Add(ref baseAddress, int.CreateTruncating(indices[i]) * scale / sizeof(TNumber)); + var idx = int.CreateTruncating(pIndices[i]); + pResult[i] = Unsafe.Add(ref baseAddress, idx * scale / sizeof(TNumber)); } - return new WideLane(Vector.Load(buffer)); + return new WideLane(result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static WideLane Gather(ref TNumber baseAddress, ref int baseIndex, int scale) { - var buffer = stackalloc TNumber[LaneWidth]; - for (var i = 0; i < LaneWidth; i++) + Unsafe.SkipInit(out Vector result); + + var pResult = (TNumber*)&result; + + var count = Vector.Count; + for (var i = 0; i < count; i++) { - buffer[i] = Unsafe.Add(ref baseAddress, Unsafe.Add(ref baseIndex, i) * scale / sizeof(TNumber)); + pResult[i] = Unsafe.Add(ref baseAddress, Unsafe.Add(ref baseIndex, i) * scale / sizeof(TNumber)); } - return new WideLane(Vector.Load(buffer)); + return new WideLane(result); } @@ -274,11 +294,9 @@ public readonly unsafe partial struct WideLane : ISPMDLane mask, TNumber* pDestination) { - var size = sizeof(TNumber); - if (LaneWidth == Vector512.Count && Vector512.IsHardwareAccelerated) { - if (size == 4) + if (sizeof(TNumber) == 4) { ref var vec = ref Unsafe.As, Vector512>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector512>(ref mask); @@ -292,7 +310,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane, Vector512>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector512>(ref mask); @@ -308,7 +326,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane.Count && Vector256.IsHardwareAccelerated) { - if (size == 4) + if (sizeof(TNumber) == 4) { ref var vec = ref Unsafe.As, Vector256>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector256>(ref mask); @@ -322,7 +340,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane, Vector256>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector256>(ref mask); @@ -340,7 +358,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane.Count && Vector128.IsHardwareAccelerated) { - if (size == 4) + if (sizeof(TNumber) == 4) { ref var vec = ref Unsafe.As, Vector128>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector128>(ref mask); @@ -354,7 +372,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane, Vector128>(ref Unsafe.AsRef(in this)); var m = Unsafe.As, Vector128>(ref mask); @@ -568,10 +586,8 @@ public readonly unsafe partial struct WideLane : ISPMDLane(Unsafe.As, Vector>(ref result)); } - else - { - return new WideLane((a.value * b.value) + c.value); - } + + return new WideLane((a.value * b.value) + c.value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -870,7 +886,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane(Unsafe.As, Vector>(ref result)); } - + return value; } @@ -1041,15 +1057,7 @@ public readonly unsafe partial struct WideLane : ISPMDLane value) { - // TODO: Use shuffle and add. - - var result = TNumber.Zero; - for (var i = 0; i < LaneWidth; i++) - { - result += value[i]; - } - - return result; + return Vector.Sum(value.value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Misaki.HighPerformance.Test/Benchmark/GGXMipGenerationBenchmark.cs b/Misaki.HighPerformance.Test/Benchmark/GGXMipGenerationBenchmark.cs index be9c071..346aaeb 100644 --- a/Misaki.HighPerformance.Test/Benchmark/GGXMipGenerationBenchmark.cs +++ b/Misaki.HighPerformance.Test/Benchmark/GGXMipGenerationBenchmark.cs @@ -1,5 +1,4 @@ using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Engines; using Misaki.HighPerformance.Image; using Misaki.HighPerformance.Jobs; @@ -396,8 +395,8 @@ public unsafe class GGXMipGenerationBenchmark [GlobalSetup] public void Setup() { - //const string imagePath = "F:\\c\\SimpleRayTracer\\native\\assets\\hdri\\golden_gate_hills_1k.hdr"; - const string imagePath = "C:\\Users\\Misaki\\Downloads\\grasslands_sunset_4k.hdr"; + const string imagePath = "F:\\c\\SimpleRayTracer\\native\\assets\\hdri\\golden_gate_hills_1k.hdr"; + //const string imagePath = "C:\\Users\\Misaki\\Downloads\\grasslands_sunset_4k.hdr"; using var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read); _image = ImageResultFloat.FromStream(stream, ColorComponents.RGB); diff --git a/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj b/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj index 6bc3608..dc84f06 100644 --- a/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj +++ b/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj @@ -6,6 +6,10 @@ enable enable True + True + Speed + avx2 + true diff --git a/Misaki.HighPerformance.Test/Program.cs b/Misaki.HighPerformance.Test/Program.cs index 2c438e1..7af3c77 100644 --- a/Misaki.HighPerformance.Test/Program.cs +++ b/Misaki.HighPerformance.Test/Program.cs @@ -8,11 +8,16 @@ using System.Runtime.InteropServices; //BenchmarkRunner.Run(); -const int count = 1; +const int count = 16; var bench = new GGXMipGenerationBenchmark(); bench.Setup(); +for (int i = 0; i < count; i++) +{ + bench.JobGGX(); +} + var sw = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < count; i++) @@ -22,7 +27,7 @@ for (int i = 0; i < count; i++) sw.Stop(); var avgTime = sw.Elapsed.TotalMilliseconds / count; -Console.WriteLine($"GGX Mip Generation: {avgTime} ms"); +Console.WriteLine($"GGX Mip Generation (Inline): {avgTime} ms"); bench.Cleanup(); //AllocationManager.Initialize(AllocationManagerInitOpts.Default);