译自官方手册,简述 Unity 另一个多线程接口,JobSystem,为 Unity ECS 系统的主要实现方式
原文
JobSystem
JobSystem 管理一组多核中的工作线程(Work Thread),为避免上下文切换通常一个逻辑核配一个工作线程
JobSystem 持有一个 Job 队列,工作线程从该队列中获取 Job 执行
Job 是执行特定任务的小工作单元,Job 可以互相依赖
线程安全
JobSystem 执行时复制而非引用数据,避免了数据竞争,但 JobSystem 只能使用memcpy
复制 blittable types 数据。Blittable types
是 .Net 框架中的数据类型,该类型数据在托管代码与原生代码间传递无需转换
NativeContainer
复制数据来保证线程安全的弊端就是任务的结果也是独立的,因此使用NativeContainer
将结果储存在公共内存中
NativeContainer
以相对安全的托管类型的方式指向一个非托管的内存地址,使Job 可以直接访问主线程数据而非复制
Unity 自带 NativeContainer
类型为 NativeArray
,ECS 包又扩展了NativeList
、NativeHashMap
、NativeMultiHashMap
和NativeQueue
默认情况下,Job 同时拥有NativeContainer
的读写权限,但 C# Job System 不允许多个 Job 同时拥有对一个NativeContainer
的写权限,因此对不需要写权限的NativeContainer
加上[ReadOnly]
特性,以减少性能影响
[ReadOnly]
public NativeArray<int> input;
JobSystem 支持多个 Job 同时读取同一数据
NativeContainer Allocator
根据 Job 执行时长决定使用哪种 Allocator
- Allocator.Temp
最快的分配方法,适用于一帧或几帧的生命时长,不能将该类型分配的数据传给 Job,在方法 Return 前执行Dispose
- Allocator.TempJob
分配速度比 Temp 慢比 Persistent 快,4帧的生命时长且线程安全。若四帧内没有调用Dispose
,控制台会打印原生代码生成的警告。大部分小任务都使用该类型分配NativeContainer
- Allocator.Persistent
是对malloc
的包装,能够维持尽可能地生命时长,性能不足的情况下不应使用
Nativ