Jobs¶
Job Types¶
In here you can find example of job types used in Stratkit. For more details, please refer to the Unity Entties Package documentation.
IJob¶
internal struct VelocityJob : IJob {
[ReadOnly]
public NativeArray<float3> velocities;
public NativeArray<float3> positions;
public float deltaTime;
public void Execute() {
for (var i = 0; i < positions.Length; i++) {
positions[i] += velocities[i] * deltaTime;
}
}
}
IJobParallelFor¶
internal struct VelocityJob : IJobParallelFor {
[ReadOnly]
public NativeArray<float3> velocities;
public NativeArray<float3> positions;
public float deltaTime;
public void Execute(int i) {
positions[i] += velocities[i] * deltaTime;
}
}
var job = new VelocityJob() {
deltaTime = Time.deltaTime,
positions = ...,
velocities = ...
};
JobHandle jobHandle = job.Schedule(positions.Length, 32);
IJobEntity¶
public struct Velocity: IComponentData {
public float3 Value;
}
public struct Position: IComponentData {
public float3 Value;
}
internal partial struct VelocityJob : IJobEntity {
public float deltaTime;
private void Execute(
in Velocity velocity,
ref Position position) {
position.Value += velocity.Value * deltaTime;
}
}
var compatibleQuery = SystemAPI.QueryBuilder()
.WithAll<Velocity, Position>()
.WithAll<BulletTag>()
.Build();
new VelocityJob().ScheduleParallel(compatibleQuery);
Jobify sequential code¶
flowchart LR
Burstify --> Jobify
Burstify code¶
Burstify code is the process of converting normal Unity's C# code into High Performance C# code. In summary:
- Remove managed component
- Use Native Container instead of maanged collections (List<T>
, T[]
, Dictionary<T1, T2>
)
- Remove all HPC# incompatible code: yield statement, interface casting, etc…
- Add BurstCompile attribute: the compiler will guide you by giving errors until it's completely Burstified
Jobify code¶
Identify repeatable code blocks
foreach (var a in arrayA) {
listB.Add(func1(a, param1));
}
param2 = func2(listB);
foreach (var a in arrayA) {
foreach (var b in arrayB) {
listC.Add(func3(a, b, param2));
}
}
internal struct Job1 : IJobParallelFor {
[ReadOnly]
public NativeArray<T> arrayA;
public NativeArray<T> arrayB;
public T param1;
public void Execute(int i) {
arrayB[i] = func1(arrayA[i], param1);
}
}
internal struct Job2 : IJob {
[ReadOnly]
public NativeArray<T> arrayB;
public NativeArray<T> output;
public void Execute() {
output[0] = func2(arrayB);
}
}
internal partial struct Job3 : IJobParallelFor {
[ReadOnly]
public NativeArray<T> arrayA;
[ReadOnly]
public NativeArray<T> arrayB;
public NativeArray<T> arrayC;
public T param2;
public void Execute(int i) {
for (int j= 0; j < arrayB.Length; j++) {
arrayC[i] = func3(arrayA[i], arrayB[j], param2);
}
}
}
// scheduling jobs
var handle1 = new Job1{ ... }.ScheduleParallel(arrayA.Length, 16, Dependency);
var handle2 = new Job2{
output = output,
...
}.Schedule(handle1);
Dependency = new Job3{
param2 = output[0],
...
}.Schedule(arrayA.Length, 16, handle2);
Jobify by using Component¶
Remodelling the relevant classes using Components
public class MyClass: MonoBehaviour {
public T a;
public T b;
public T c;
public void Update() {
c = func1(a, b);
}
}
internal partial struct MyClassJob : IJobEntity {
private void Execute(in AB ab, ref C c) {
c = func1(ab.a, ab.b);
}
}
Reverse one-to-many relationship¶
Refer to this refactoring pattern