I was wondering what is better to have two jobs that do same small tasks one after another (one with if statement) or is better to combine them into one. From my test, it turned out that two jobs are slightly better despite I go thru all the elements twice. But just for comparison, I have recreated the same logic in a standard for loop and the outcome have surprised me. A single-threaded code was 5 times faster. Here is my code:
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
public class TEST : MonoBehaviour
{
public int Count = 5000000;
public bool one = true;
public bool normal = false;
private NativeArray<float> _floats;
private float[] _array;
private void Start()
{
_floats = new NativeArray<float>(Count, Allocator.Persistent);
var job = new InitJob()
{
counters = _floats,
init = 3
}.Schedule(Count, 64);
job.Complete();
_array = _floats.ToArray();
}
private struct InitJob : IJobParallelFor
{
public NativeArray<float> counters;
public float init;
public void Execute(int index)
{
counters[index] = init;
}
}
private struct DecreaseJob : IJobParallelFor
{
public NativeArray<float> counters;
public float deltaTime;
public void Execute(int index)
{
counters[index] -= deltaTime;
}
}
private struct DecreaseAndReset : IJobParallelFor
{
public NativeArray<float> counters;
public float deltaTime;
public float init;
public void Execute(int index)
{
counters[index] -= deltaTime;
if (counters[index] < 0)
counters[index] = init;
}
}
private struct ResetJob : IJobParallelFor
{
public NativeArray<float> counters;
public float init;
public void Execute(int index)
{
if (counters[index] < 0)
counters[index] = init;
}
}
private void Update()
{
if (normal)
{
var deltaTime = Time.deltaTime;
for (int i = _array.Length - 1; i >= 0; i--)
{
_array[i] -= deltaTime;
if (_array[i] < 0)
_array[i] = 3;
}
}
else
if (one)
One();
else
Two();
}
public void Two()
{
var jobhandle = new DecreaseJob()
{
counters = _floats,
deltaTime = Time.deltaTime
}.Schedule(Count, 64);
var second = new ResetJob()
{
counters = _floats,
init = 3
}.Schedule(Count, 64, jobhandle);
second.Complete();
}
public void One()
{
var jobhandle = new DecreaseAndReset()
{
counters = _floats,
deltaTime = Time.deltaTime,
init = 3
}.Schedule(Count, 64);
jobhandle.Complete();
}
private void OnDestroy()
{
_floats.Dispose();
}
}
Am I doing something wrong in my jobs?
I am using Unity 2018.2.3f1.
edit:
I have added burst compiler and now things have changed.
A normal way is 5 times slower, two jobs vs one are comparable.
But still why without burst it is that much slower it uses 8 cores so that alone should give a nice boost.