Update Job
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
using Misaki.HighPerformance.Jobs;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using static Misaki.HighPerformance.Mathematics.math;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.Jobs;
|
||||
@@ -7,10 +7,12 @@ namespace Misaki.HighPerformance.Test.Jobs;
|
||||
public static partial class noise
|
||||
{
|
||||
// Modulo 289 without a division (only multiplications)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float mod289(float x)
|
||||
{
|
||||
return x - floor(x * (1.0f / 289.0f)) * 289.0f;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float2 mod289(float2 x)
|
||||
{
|
||||
return x - floor(x * (1.0f / 289.0f)) * 289.0f;
|
||||
@@ -74,7 +76,7 @@ public static partial class noise
|
||||
{
|
||||
var ones = float4(1.0f, 1.0f, 1.0f, -1.0f);
|
||||
var pxyz = floor(frac(float3(j) * ip.xyz) * 7.0f) * ip.z - 1.0f;
|
||||
float pw = 1.5f - dot(abs(pxyz), ones.xyz);
|
||||
var pw = 1.5f - dot(abs(pxyz), ones.xyz);
|
||||
var p = float4(pxyz, pw);
|
||||
var s = float4(p < 0.0f);
|
||||
p.xyz = p.xyz + (s.xyz * 2.0f - 1.0f) * s.www;
|
||||
@@ -86,96 +88,8 @@ public static partial class noise
|
||||
public static float2 rgrad2(float2 p, float rot)
|
||||
{
|
||||
// For more isotropic gradients, math.sin/math.cos can be used instead.
|
||||
float u = permute(permute(p.x) + p.y) * 0.0243902439f + rot; // Rotate by shift
|
||||
var u = permute(permute(p.x) + p.y) * 0.0243902439f + rot; // Rotate by shift
|
||||
u = frac(u) * 6.28318530718f; // 2*pi
|
||||
return float2(cos(u), sin(u));
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe struct NoiseJob3D : IJobParallelFor
|
||||
{
|
||||
public float* buffers;
|
||||
|
||||
public int size; // size x size x size
|
||||
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
{
|
||||
var v = float3(
|
||||
(loopIndex % size) / (float)size,
|
||||
((loopIndex / size) % size) / (float)size,
|
||||
(loopIndex / (size * size)) / (float)size
|
||||
);
|
||||
|
||||
var C = float2(1.0f / 6.0f, 1.0f / 3.0f);
|
||||
var D = float4(0.0f, 0.5f, 1.0f, 2.0f);
|
||||
|
||||
// First corner
|
||||
var i = floor(v + dot(v, C.yyy));
|
||||
var x0 = v - i + dot(i, C.xxx);
|
||||
|
||||
// Other corners
|
||||
var g = step(x0.yzx, x0.xyz);
|
||||
var l = 1.0f - g;
|
||||
var i1 = min(g.xyz, l.zxy);
|
||||
var i2 = max(g.xyz, l.zxy);
|
||||
|
||||
// x0 = x0 - 0.0 + 0.0 * C.xxx;
|
||||
// x1 = x0 - i1 + 1.0 * C.xxx;
|
||||
// x2 = x0 - i2 + 2.0 * C.xxx;
|
||||
// x3 = x0 - 1.0 + 3.0 * C.xxx;
|
||||
var x1 = x0 - i1 + C.xxx;
|
||||
var x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
|
||||
var x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
|
||||
|
||||
// Permutations
|
||||
i = noise.mod289(i);
|
||||
var p = noise.permute(noise.permute(noise.permute(
|
||||
i.z + float4(0.0f, i1.z, i2.z, 1.0f))
|
||||
+ i.y + float4(0.0f, i1.y, i2.y, 1.0f))
|
||||
+ i.x + float4(0.0f, i1.x, i2.x, 1.0f));
|
||||
|
||||
// Gradients: 7x7 points over a square, mapped onto an octahedron.
|
||||
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
|
||||
float n_ = 0.142857142857f; // 1.0/7.0
|
||||
var ns = n_ * D.wyz - D.xzx;
|
||||
|
||||
var j = p - 49.0f * floor(p * ns.z * ns.z); // math.mod(p,7*7)
|
||||
|
||||
var x_ = floor(j * ns.z);
|
||||
var y_ = floor(j - 7.0f * x_); // math.mod(j,N)
|
||||
|
||||
var x = x_ * ns.x + ns.yyyy;
|
||||
var y = y_ * ns.x + ns.yyyy;
|
||||
var h = 1.0f - abs(x) - abs(y);
|
||||
|
||||
var b0 = float4(x.xy, y.xy);
|
||||
var b1 = float4(x.zw, y.zw);
|
||||
|
||||
//float4 s0 = float4(math.lessThan(b0,0.0))*2.0 - 1.0;
|
||||
//float4 s1 = float4(math.lessThan(b1,0.0))*2.0 - 1.0;
|
||||
var s0 = floor(b0) * 2.0f + 1.0f;
|
||||
var s1 = floor(b1) * 2.0f + 1.0f;
|
||||
var sh = -step(h, float4(0.0f));
|
||||
|
||||
var a0 = b0.xzyw + s0.xzyw * sh.xxyy;
|
||||
var a1 = b1.xzyw + s1.xzyw * sh.zzww;
|
||||
|
||||
var p0 = float3(a0.xy, h.x);
|
||||
var p1 = float3(a0.zw, h.y);
|
||||
var p2 = float3(a1.xy, h.z);
|
||||
var p3 = float3(a1.zw, h.w);
|
||||
|
||||
//Normalise gradients
|
||||
var norm = noise.taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
|
||||
p0 *= norm.x;
|
||||
p1 *= norm.y;
|
||||
p2 *= norm.z;
|
||||
p3 *= norm.w;
|
||||
|
||||
// Mix final noise value
|
||||
var m = max(0.6f - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0f);
|
||||
m *= m;
|
||||
|
||||
buffers[loopIndex] = 42.0f * dot(m * m, float4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Misaki.HighPerformance.Jobs;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
using Misaki.HighPerformance.Mathematics.SPMD;
|
||||
using System.Numerics;
|
||||
@@ -8,7 +7,22 @@ using System.Runtime.Intrinsics;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.Jobs;
|
||||
|
||||
internal unsafe struct NoiseJobVector : IJobParallelFor
|
||||
internal unsafe struct NoiseJobVectorFor : IJobParallelFor
|
||||
{
|
||||
public float* buffers;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
{
|
||||
var x = loopIndex % width;
|
||||
var y = loopIndex / height;
|
||||
var uv = new Vector2(x, y) / new Vector2(width, height);
|
||||
buffers[loopIndex] = NoiseJobVector.GradientNoise(uv);
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe struct NoiseJobVector : IJobParallel
|
||||
{
|
||||
public float* buffers;
|
||||
public int width;
|
||||
@@ -20,16 +34,23 @@ internal unsafe struct NoiseJobVector : IJobParallelFor
|
||||
return x - MathF.Floor(x);
|
||||
}
|
||||
|
||||
private static float Mod289(float x)
|
||||
{
|
||||
return x - MathF.Floor(x / 289) * 289;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static Vector2 GradientNoiseDirect(Vector2 uv)
|
||||
{
|
||||
uv.X %= 289;
|
||||
uv.Y %= 289;
|
||||
var x = (34 * uv.X + 1) * uv.X % 289 + uv.Y;
|
||||
x = (34 * x + 1) * x % 289;
|
||||
uv.X = Mod289(uv.X);
|
||||
uv.Y = Mod289(uv.Y);
|
||||
var x = (34 * uv.X + 1) * Mod289(uv.X) + uv.Y;
|
||||
x = (34 * x + 1) * Mod289(x);
|
||||
x = Frac(x / 41) * 2 - 1;
|
||||
return Vector2.Normalize(new Vector2(x - MathF.Floor(x + 0.5f), MathF.Abs(x) - 0.5f));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float GradientNoise(Vector2 uv)
|
||||
{
|
||||
var ip = new Vector2(MathF.Floor(uv.X), MathF.Floor(uv.Y));
|
||||
@@ -44,30 +65,35 @@ internal unsafe struct NoiseJobVector : IJobParallelFor
|
||||
return float.Lerp(float.Lerp(d00, d10, fp.Y), float.Lerp(d01, d11, fp.Y), fp.X);
|
||||
}
|
||||
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
public void Execute(int startIndex, int endIndex, int threadIndex)
|
||||
{
|
||||
var x = loopIndex % width;
|
||||
var y = loopIndex / height;
|
||||
var uv = new Vector2(x, y) / new Vector2(width, height);
|
||||
buffers[loopIndex] = GradientNoise(uv);
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
var x = i % width;
|
||||
var y = i / height;
|
||||
var uv = new Vector2(x, y) / new Vector2(width, height);
|
||||
buffers[i] = GradientNoise(uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe struct NoiseJobMath : IJobParallelFor
|
||||
internal unsafe struct NoiseJobMath : IJobParallel
|
||||
{
|
||||
public float* buffers;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static float2 GradientNoiseDirect(float2 uv)
|
||||
{
|
||||
uv %= 289;
|
||||
var x = (34 * uv.x + 1) * uv.x % 289 + uv.y;
|
||||
x = (34 * x + 1) * x % 289;
|
||||
uv = noise.mod289(uv);
|
||||
var x = (34 * uv.x + 1) * noise.mod289(uv.x) + uv.y;
|
||||
x = (34 * x + 1) * noise.mod289(x);
|
||||
x = math.frac(x / 41) * 2 - 1;
|
||||
return math.normalize(new float2(x - math.floor(x + 0.5f), math.abs(x) - 0.5f));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float GradientNoise(float2 uv)
|
||||
{
|
||||
var ip = new float2(math.floor(uv.x), math.floor(uv.y));
|
||||
@@ -82,6 +108,7 @@ internal unsafe struct NoiseJobMath : IJobParallelFor
|
||||
return float.Lerp(float.Lerp(d00, d10, fp.y), float.Lerp(d01, d11, fp.y), fp.x);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
{
|
||||
var x = loopIndex % width;
|
||||
@@ -89,9 +116,21 @@ internal unsafe struct NoiseJobMath : IJobParallelFor
|
||||
var uv = new float2(x, y) / new float2(width, height);
|
||||
buffers[loopIndex] = GradientNoise(uv);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Execute(int startIndex, int endIndex, int threadIndex)
|
||||
{
|
||||
for (var i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
var x = i % width;
|
||||
var y = i / height;
|
||||
var uv = new float2(x, y) / new float2(width, height);
|
||||
buffers[i] = GradientNoise(uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe struct NoiseJobMathV : IJobParallelFor
|
||||
internal unsafe struct NoiseJobMathV : IJobParallel
|
||||
{
|
||||
public float* buffers;
|
||||
public int width;
|
||||
@@ -160,35 +199,35 @@ internal unsafe struct NoiseJobMathV : IJobParallelFor
|
||||
return lerpY1 + (lerpY2 - lerpY1) * uX;
|
||||
}
|
||||
|
||||
public void Execute(int loopIndex, int threadIndex)
|
||||
public void Execute(int startIndex, int endIndex, int threadIndex)
|
||||
{
|
||||
// ---------------------------------------------------------
|
||||
// IMPORTANT: Loop Stride is now 8!
|
||||
// ---------------------------------------------------------
|
||||
var baseIndex = loopIndex * 8;
|
||||
|
||||
// Safety check
|
||||
if (baseIndex + 7 >= width * height)
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
return;
|
||||
var baseIndex = i * 8;
|
||||
|
||||
// Safety check
|
||||
if (baseIndex + 7 >= width * height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate Coords
|
||||
var y = baseIndex / width;
|
||||
var x = baseIndex % width;
|
||||
|
||||
// Sequence: 0, 1, 2, 3, 4, 5, 6, 7
|
||||
var vSeqX = Vector256.Create(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f);
|
||||
var vBaseX = Vector256.Create((float)x) + vSeqX;
|
||||
var vBaseY = Vector256.Create((float)y);
|
||||
|
||||
var vWidth = Vector256.Create((float)width);
|
||||
var vHeight = Vector256.Create((float)height);
|
||||
|
||||
var result = GradientNoiseAVX(vBaseX / vWidth, vBaseY / vHeight);
|
||||
|
||||
// Store 8 floats (32 bytes)
|
||||
result.Store(buffers + baseIndex);
|
||||
}
|
||||
|
||||
// Calculate Coords
|
||||
var y = baseIndex / width;
|
||||
var x = baseIndex % width;
|
||||
|
||||
// Sequence: 0, 1, 2, 3, 4, 5, 6, 7
|
||||
var vSeqX = Vector256.Create(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f);
|
||||
var vBaseX = Vector256.Create((float)x) + vSeqX;
|
||||
var vBaseY = Vector256.Create((float)y);
|
||||
|
||||
var vWidth = Vector256.Create((float)width);
|
||||
var vHeight = Vector256.Create((float)height);
|
||||
|
||||
var result = GradientNoiseAVX(vBaseX / vWidth, vBaseY / vHeight);
|
||||
|
||||
// Store 8 floats (32 bytes)
|
||||
result.Store(buffers + baseIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user