123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using Unity.Jobs;
- using Unity.Mathematics;
-
- [assembly: InternalsVisibleTo("Burst.Benchmarks")]
-
- namespace UnityBenchShared
- {
- internal struct Sphere
- {
- private float x, y, z, r;
-
- public Sphere(float x, float y, float z, float r)
- {
- this.x = x;
- this.y = y;
- this.z = z;
- this.r = r;
- }
-
- public bool Intersects(Sphere other)
- {
- float dx = x - other.x;
- float dy = y - other.y;
- float dz = z - other.z;
- float rs = r + other.r;
- return dx * dx + dy * dy + dz * dz < (rs * rs);
- }
- }
-
- internal static class SphereCulling
- {
- public static int BenchCount = 128 * 1024 + 3;
- }
-
- internal interface IJob<T> : IJob
- {
- T Result { get; set; }
- }
-
-
- /// <summary>
- /// Simple AOS with a Sphere struct using plain floats
- /// </summary>
- internal struct SphereCullingAOSJob : IJob<bool>, IDisposable
- {
- public Sphere Against;
-
- [ReadOnly] public NativeArray<Sphere> Spheres;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public void Execute()
- {
- bool result = false;
- for (int i = 0; i < Spheres.Length; ++i)
- {
- result |= Spheres[i].Intersects(Against);
- }
-
- Result = result;
- }
-
- public struct Provider : IArgumentProvider
- {
- public object Value
- {
- get
- {
- int length = SphereCulling.BenchCount * 2;
- var job = new SphereCullingAOSJob()
- {
- Spheres = new NativeArray<Sphere>(length, Allocator.Persistent),
- Against = new Sphere(0, 0, 0, 1)
- };
-
- var random = new System.Random(0);
- for (int i = 0; i < job.Spheres.Length; i++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.Spheres.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
- job.Spheres[i] = new Sphere(x, x, x, 1.0f);
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- Spheres.Dispose();
- }
- }
-
- /// <summary>
- /// Simple AOS with a float4 for the struct and using
- /// </summary>
- internal struct SphereCullingFloat4AOSJob : IJob<bool>, IDisposable
- {
- public float4 Against;
-
- [ReadOnly]
- public NativeArray<float4> Spheres;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public static bool Intersects(float4 value, float4 other)
- {
- float rs = value.w + other.w;
- return math.dot(value.xyz, other.xyz) < (rs * rs);
- }
-
- public void Execute()
- {
- bool result = false;
- for (int i = 0; i < Spheres.Length; ++i)
- {
- result |= Intersects(Spheres[i], Against);
- }
-
- Result = result;
- }
-
- public struct Provider : IArgumentProvider
- {
- public object Value
- {
- get
- {
- int length = SphereCulling.BenchCount;
- var job = new SphereCullingFloat4AOSJob()
- {
- Spheres = new NativeArray<float4>(length, Allocator.Persistent),
- Against = new float4(0, 0, 0, 1)
- };
-
- var random = new System.Random(0);
- for (int i = 0; i < job.Spheres.Length; i++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.Spheres.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
- job.Spheres[i] = new float4(x, x, x, 1.0f);
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- Spheres.Dispose();
- }
- }
-
- /// <summary>
- /// Simple SOA with 4 NativeArray for X,Y,Z,R
- /// </summary>
- internal struct SphereCullingSOAJob : IJob<bool>, IDisposable
- {
- [ReadOnly] public NativeArray<float> X;
- [ReadOnly] public NativeArray<float> Y;
- [ReadOnly] public NativeArray<float> Z;
- [ReadOnly] public NativeArray<float> R;
-
- public float4 Against;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public void Execute()
- {
- bool result = false;
-
- for (int i = 0; i < X.Length; ++i)
- {
- float dx = X[i] - Against.x;
- float dy = Y[i] - Against.y;
- float dz = Z[i] - Against.z;
- float rs = R[i] + Against.w;
- result |= dx * dx + dy * dy + dz * dz < (rs * rs);
- }
-
- Result = result;
- }
-
- public struct Provider : IArgumentProvider
- {
- public object Value
- {
- get
- {
- int length = SphereCulling.BenchCount * 2;
- var job = new SphereCullingSOAJob()
- {
- X = new NativeArray<float>(length, Allocator.Persistent),
- Y = new NativeArray<float>(length, Allocator.Persistent),
- Z = new NativeArray<float>(length, Allocator.Persistent),
- R = new NativeArray<float>(length, Allocator.Persistent),
- Against = new float4(0, 0, 0, 1)
- };
-
-
- var random = new System.Random(0);
- for (int i = 0; i < job.X.Length; i++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.X.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
- job.X[i] = x;
- job.Y[i] = x;
- job.Z[i] = x;
- job.R[i] = 1;
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- X.Dispose();
- Y.Dispose();
- Z.Dispose();
- R.Dispose();
- }
- }
-
- /// <summary>
- /// SOA with chunks of x,y,z,r using `float4`
- /// </summary>
- internal struct SphereCullingChunkSOAJob : IJob<bool>, IDisposable
- {
- public struct Chunk
- {
- public float4 X;
- public float4 Y;
- public float4 Z;
- public float4 R;
- }
-
- [ReadOnly] public NativeArray<Chunk> Chunks;
-
- public float4 Against;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public void Execute()
- {
- bool result = false;
-
- for (int i = 0; i < Chunks.Length; ++i)
- {
- var chunk = Chunks[i];
- for (int j = 0; j < 4; j++)
- {
- float dx = chunk.X[j] - Against.x;
- float dy = chunk.Y[j] - Against.y;
- float dz = chunk.Z[j] - Against.z;
- float rs = chunk.R[j] + Against.w;
- result |= dx * dx + dy * dy + dz * dz < (rs * rs);
- }
- }
-
- Result = result;
- }
-
- public struct Provider : IArgumentProvider
- {
- public object Value
- {
- get
- {
- // Approximate a similar batch
- int length = ((SphereCulling.BenchCount * 2) + 4) / 4;
- var job = new SphereCullingChunkSOAJob
- {
- Chunks = new NativeArray<SphereCullingChunkSOAJob.Chunk>(length, Allocator.Persistent),
- Against = new float4(0, 0, 0, 1)
- };
-
- var random = new System.Random(0);
- for (int i = 0; i < job.Chunks.Length; i++)
- {
- var chunk = job.Chunks[i];
- for (int j = 0; j < 4; j++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.Chunks.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
-
- chunk.X[j] = x;
- chunk.Y[j] = x;
- chunk.Z[j] = x;
- chunk.R[j] = 1;
- }
- job.Chunks[i] = chunk;
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- Chunks.Dispose();
- }
- }
-
- /// <summary>
- /// SOA with chunks of x,y,z,r using `fixed float x[4]`
- /// </summary>
- internal struct SphereCullingChunkFixedSOAJob : IJob<bool>, IDisposable
- {
- public unsafe struct Chunk
- {
- public fixed float X[4];
- public fixed float Y[4];
- public fixed float Z[4];
- public fixed float R[4];
- }
-
- [ReadOnly] public NativeArray<Chunk> Chunks;
-
- public float4 Against;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public unsafe void Execute()
- {
- bool result = false;
-
- for (int i = 0; i < Chunks.Length; ++i)
- {
- var chunk = Chunks[i];
- for (int j = 0; j < 4; j++)
- {
- float dx = chunk.X[j] - Against.x;
- float dy = chunk.Y[j] - Against.y;
- float dz = chunk.Z[j] - Against.z;
- float rs = chunk.R[j] + Against.w;
- result |= dx * dx + dy * dy + dz * dz < (rs * rs);
- }
- }
-
- Result = result;
- }
-
- public struct Provider : IArgumentProvider
- {
- public unsafe object Value
- {
- get
- {
- // Approximate a similar batch
- int length = ((SphereCulling.BenchCount) + 4) / 2;
- var job = new SphereCullingChunkFixedSOAJob
- {
- Chunks = new NativeArray<Chunk>(length, Allocator.Persistent),
- Against = new float4(0, 0, 0, 1)
- };
-
- var random = new System.Random(0);
- for (int i = 0; i < job.Chunks.Length; i++)
- {
- var chunk = job.Chunks[i];
- for (int j = 0; j < 4; j++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.Chunks.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
- chunk.X[j] = x;
- chunk.Y[j] = x;
- chunk.Z[j] = x;
- chunk.R[j] = 1;
- }
- job.Chunks[i] = chunk;
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- Chunks.Dispose();
- }
- }
-
- /// <summary>
- /// </summary>
- internal struct SphereCullingChunkSOAManualJob : IJob<bool>, IDisposable
- {
- public struct Chunk
- {
- public float4 X;
- public float4 Y;
- public float4 Z;
- public float4 R;
- }
-
- [ReadOnly] public NativeArray<Chunk> Chunks;
-
- public float4 Against;
-
- [MarshalAs(UnmanagedType.U1)]
- private bool result;
-
- public bool Result
- {
- get => result;
- set => result = value;
- }
-
- public void Execute()
- {
- bool4 result = false;
-
- for (int i = 0; i < Chunks.Length; ++i)
- {
- var chunk = Chunks[i];
- float4 dx = chunk.X - Against.x;
- float4 dy = chunk.Y - Against.y;
- float4 dz = chunk.Z - Against.z;
- float4 rs = chunk.R + Against.w;
- result |= dx * dx + dy * dy + dz * dz < (rs * rs);
- }
-
- Result = math.any(result);
- }
-
- public struct Provider : IArgumentProvider
- {
- public object Value
- {
- get
- {
- // Approximate a similar batch
- int length = (SphereCulling.BenchCount + 4) / 4;
- var job = new SphereCullingChunkSOAManualJob
- {
- Chunks = new NativeArray<SphereCullingChunkSOAManualJob.Chunk>(length, Allocator.Persistent),
- Against = new float4(0, 0, 0, 1)
- };
-
- var random = new System.Random(0);
- for (int i = 0; i < job.Chunks.Length; i++)
- {
- var chunk = job.Chunks[i];
- for (int j = 0; j < 4; j++)
- {
- // Most don't intersects
- var x = random.Next(100) + 3.0f;
- if (i == job.Chunks.Length / 2)
- {
- // only this one
- x = 0.5f;
- }
-
- chunk.X[j] = x;
- chunk.Y[j] = x;
- chunk.Z[j] = x;
- chunk.R[j] = 1;
- }
- job.Chunks[i] = chunk;
- }
-
- return job;
- }
- }
- }
-
- public void Dispose()
- {
- Chunks.Dispose();
- }
- }
- }
|