作者介绍:铸梦xy。IT公司技术合伙人,IT高级讲师,资深Unity架构师,铸梦之路系列课程创始人。
前言
这篇文章会让你真正的认识到JobSystem的强大之处,并且还会感受到DOTS的恐怖之处!
那么下面我们通过实践测试来见证一下。
1.什么是Job System
Job System (作业系统) 可以理解为多线程管理系统
我们通过Job System就可以编写与Unity其他部件交互的多线程代码,同时让编写正确的多线程代码变得更容易。
编写多线程代码可以提供更好的性能表现。这包括极大的提升提升和手机上更久的续航。
Job System的一个非常关键的方面是它可以融入Unity内部的原生Job System。这使得用户的代码可以和Unity共享worker threads。这种合作避免了创建更多线程,因为这可能会造成对于CPU资源的争抢。
3.概述
在Job System中我们会使用到一种新的类型NativeContainer。它是一种托管值类型,为本机内存提供了一个相对安全的 C# 封装器,它包含一个指向非托管分配的指针。
与 Job System一起使用时,NativeContainer允许Job访问与主线程共享的数据,而不是拷贝数据。如果是拷贝数据会导致同样的数据到不同的Job中,其结果是相互隔离的,因此我们需要将结果存储在共享内存中,也就是NativeContainer。
Unity 附带了一个名为NativeArray的NativeContainer,用来代替传统的数组(T[])。
ECS为其进行了拓展Unity.Collections命名空间以包含其他类型的 NativeContainer:
- NativeList - 可调整大小的 NativeArray,类似于List
- NativeHashMap<T, R> - 键/值对,类似于Dictionary<T, R>
- NativeMultiHashMap<T, R> - 每个键有多个值。
- NativeQueue - 先进先出队列,类似于Queue
创建 NativeContainer 时,必须指定所需的内存分配类型(Allocator),分配类型取决于Job运行的时间。设置不同的值以便在每种情况下获得最佳性能。
Allocator.Temp - 具有最快的分配速度。此类型适用于寿命为一帧或更短的分配。不应该使用 Temp 将 NativeContainer 分配传递给Job。在从方法调用返回之前,需要调用 Dispose 方法。
Allocator.TempJob - 的分配速度比 Temp 慢,但比 Persistent 快。此类型适用于寿命为四帧的分配,并具有线程安全性。如果没有在四帧内对其执行 Dispose 方法,控制台会输出警告。大多数逻辑量少的Job都使用这种类型。
Allocator.Persistent - 是最慢的分配,但可以在您所需的任意时间内持续存在,如果有必要,可以在整个应用程序的生命周期内存在。此分配器是直接调用 malloc 的封装器。持续时间较长的Job可以使用这种类型。在非常注重性能的情况下不应使用 Persistent。
例如:
NativeArray result = new NativeArray(10, Allocator.TempJob);
注:使用NativeContainer需要我们手动Dispose,而不是等GC的时候自动释放
3.JobSystem 使用介绍
一个简单job定义的例子
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
在合适的时间调用Schedule将job放入到job的执行队列中。一旦job被调度,你不能中途打断一个job的执行。
注意:你只能从主线程中调用Schedule
void Update()
{
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result

最低0.47元/天 解锁文章
522





