Skip to content

Instantly share code, notes, and snippets.

@marijnz
Last active January 12, 2021 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marijnz/a8b611331a1ff068b230183674780879 to your computer and use it in GitHub Desktop.
Save marijnz/a8b611331a1ff068b230183674780879 to your computer and use it in GitHub Desktop.
Unity Job.Run vs Function Pointer, both bursted
class BurstTest
{
[BurstCompile]
public struct MultJob : IJob
{
[ReadOnly]
public NativeArray<float> a;
[ReadOnly]
public NativeArray<float> b;
[WriteOnly]
public NativeArray<float> result;
public void Execute()
{
for (int i = 0; i < a.Length; i++)
{
result[i] = a[i] * b[i];
}
}
}
[BurstCompile]
class Funcs
{
public delegate void MultArraysDel(ref NativeArray<float> a, ref NativeArray<float> b, ref NativeArray<float> result);
[BurstCompile]
public static void MultArrays(ref NativeArray<float> a, ref NativeArray<float> b, ref NativeArray<float> result)
{
for (int i = 0; i < a.Length; i++)
{
result[i] = a[i] * b[i];
}
}
}
[Test]
public void BurstFuncPointerTest()
{
var a = new NativeArray<float>(500, Allocator.TempJob);
var b = new NativeArray<float>(500, Allocator.TempJob);
var r = new NativeArray<float>(500, Allocator.TempJob);
var funcPointer = BurstCompiler.CompileFunctionPointer<Funcs.MultArraysDel>(Funcs.MultArrays);
funcPointer.Invoke(ref a, ref b, ref r);
var s = Stopwatch.StartNew();
for (int i = 0; i < 500; i++)
{
funcPointer.Invoke(ref a, ref b, ref r);
}
Debug.Log("func pointer: " + s.Elapsed.TotalMilliseconds);
new MultJob { a = a, b = b, result = r }.Run();
s.Restart();
for (int i = 0; i < 500; i++)
{
new MultJob { a = a, b = b, result = r }.Run();
}
Debug.Log("job run: " + s.Elapsed.TotalMilliseconds);
a.Dispose();
b.Dispose();
r.Dispose();
}
}
@cbaggers
Copy link

cbaggers commented Jan 12, 2021

Thanks for sharing this gist. I was curious about the timings too

    static void BurstFuncPointerTest()
    {
        var a = new NativeArray<float>(5000, Allocator.TempJob);
        var b = new NativeArray<float>(5000, Allocator.TempJob);
        var r = new NativeArray<float>(5000, Allocator.TempJob);

        var funcPointer = BurstCompiler.CompileFunctionPointer<Funcs.MultArraysDel>(Funcs.MultArrays);
        var fp = funcPointer.Invoke;
        fp(ref a, ref b, ref r);

        for (var x = 0; x < 10; x++)
        {
            var s = Stopwatch.StartNew();
            for (var i = 0; i < 5000; i++)
            {
                fp(ref a, ref b, ref r);
            }
            Debug.Log("func pointer: " + s.Elapsed.TotalMilliseconds);

            new MultJob { a = a, b = b, result = r }.Run();

            s.Restart();
            for (var i = 0; i < 5000; i++)
            {
                new MultJob { a = a, b = b, result = r }.Run();
            }
            Debug.Log("job run: " + s.Elapsed.TotalMilliseconds);
        }

        a.Dispose();
        b.Dispose();
        r.Dispose();
    }

tweaked for more iterations and to cache the invoke method. For me this made the function-pointer approach faster than the IJob.Run approach (when in the original version IJob.Run was faster on my machine)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment