Unity2023.1.19_DOTS_JobSystem
上篇我们知道了DOTS是包含Entity Component System,Job System,Burst compiler三者的。接下来看下JobSystem的工作原理和具体实现。
简介:
官方介绍说:JobSystem允许您编写简单而安全的多线程代码,以便您的应用程序可以使用所有可用的CPU内核来执行代码。也就是说JobSystem是为多线程服务的一个模块。
JobSystem可以单独使用,但为了提高性能,也还应该使用Burst compiler,Burst compiler是专门为Unity的JobSystem编译而设计的。urst compiler改进了代码生成,从而提高了性能并减少了移动设备上的电池消耗。Burst compiler将在JobSystem之后再关注。
JobSystem和Burst compiler一起使用的时候,JobSystem工作效果最好。因为Burst不支持托管对象,所以需要使用非托管类型来访问Job中的数据。你可以使用blittable types,或者使用Unity内置的Native container对象,这是一个线程安全的c#本机内存包装器。NativeContainer对象还允许job访问与主线程共享的数据,而不是使用副本。
ECS为其进行了拓展Unity.Collections命名空间以包含其他类型的 NativeContainer:
NativeList - 可调整大小的 NativeArray,类似于List
NativeHashMap<T, R> - 键/值对,类似于Dictionary<T, R>
NativeMultiHashMap<T, R> - 每个键有多个值。
NativeQueue - 先进先出队列,类似于Queue
也可以在ECS中使用JobSystem创建高性能的面向数据代码。
Collections Package提供可在job和Burst-compiled代码中使用的非托管数据结构。
Unity使用原生的JobSystem处理原生代码使用多个工作线程,工作线程取决于你应用程序运行设备的CPU核的可用数量。
通常Unity默认在程序开始时在一个主线程上执行你的代码,你可以使用JobSystem在多个工作线程上执行你的代码,称之为多线程。
简单代码说明:
using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
// Job adding two floating point values together
// It implements IJob, uses a NativeArray to get the results of the job, and uses the Execute method with the implementation of the job inside it:
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
下面的例子建立在MyJob任务上,在主线程上调度一个任务:
using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
public class MyScheduledJob : MonoBehaviour
{
// Create a native array of a single float to store the result.
// Using a NativeArray is the only way you can get the results of the job, whether you're getting one value or an array of values.
NativeArray<float> result;
// Create a JobHandle for the job
// 给任务创建一个任务处理
JobHandle handle;
// Set up the job
// 创建一个任务
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// Update is called once per frame
// 每一帧更新
void Update()
{
// Set up the job data 设置任务数据
result = new NativeArray<float>(1, Allocator.TempJob);
MyJob jobData = new MyJob
{
a = 10,
b = 10,
result = result
};
// Schedule the job 安排任务
handle = jobData.Schedule();
}
private void LateUpdate()
{
// Sometime later in the frame, wait for the job to complete before accessing the results.
// 稍后在框架中,等待作业完成后再访问结果。
handle.Complete();
// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
// float aPlusB = result[0];
// Free the memory allocated by the result array
// 释放由结果数组分配的内存
result.Dispose();
}
}
跟一个测试:
using UnityEngine;
using Unity.Collections;
using Unity.Jobs;
public class MyScheduledJob : MonoBehaviour
{
// Create a native array of a single float to store the result.
// Using a NativeArray is the only way you can get the results of the job, whether you're getting one value or an array of values.
NativeArray<float> result;
// Create a JobHandle for the job
// 给任务创建一个任务处理
JobHandle handle;
// Set up the job
// 创建一个任务
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// Update is called once per frame
// 每一帧更新
void Update()
{
// Set up the job data 设置任务数据
result = new NativeArray<float>(1, Allocator.TempJob);
MyJob jobData = new MyJob
{
a = 10,
b = 10,
result = result
};
// Schedule the job 安排任务
handle = jobData.Schedule();
}
private void LateUpdate()
{
// Sometime later in the frame, wait for the job to complete before accessing the results.
// 稍后在框架中,等待作业完成后再访问结果。
handle.Complete();
// All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
// float aPlusB = result[0];
// Free the memory allocated by the result array
// 释放由结果数组分配的内存
result.Dispose();
}
}
意思大概是这样了,具体实践具体看!!
参考文档:
官方文档
Unity - Manual: Job system overview (unity3d.com)
Collections package | Collections | 2.2.1 (unity3d.com)
Unity - Manual: Thread safe types (unity3d.com)
这个博主系列的讲到了DOTS,可以看一下:
DOTS ECS_铸梦xy的博客-CSDN博客