Unity Jobs System
- 包含C# Jobs System和C++ Jobs System
- 利用多核计算平台来简单安全的编写与执行多线程代码
- 既可以与ECS结合使用也可以单独使用
- 编写代码时不需要关心运行平台CPU核心情况与线程资源的情况
Job System的调度
- Jobs System是通过创建Job任务,而不是线程,来管理多线程代码的
- Unity引擎内部会跨多个核心来管理一组工作线程,以避免上下文的切换
- 执行时,Jobs System会将我们创建的Job任务放到Job队列中,以等待
执行 - 工作线程会从Job队列中获取并执行相应的工作
C# Jobs System
- 一般不会出现手写多线程程序中出现的Race Conditions问题
- 因为在每个Job任务中,只访问数据的拷贝
- 或者是转换一段buffer的所有权给这个Job(Native Container)
- C# Jobs System实际上使用的就是Unity引擎内C++ Jobs System的代码
- 所以在引擎与游戏线程之间没有上下文切换的开销
- 但毕竟C#与C++下的内存管理与值的类型定义不同,所以在写C# Jobs System代码时,需要区别哪些是Blittable Type类型的数据,哪些类型不是
Blittable Types VS Non-Blittable Types
- Blittable Types : 在托管代码和非托管代码的内存中具有相同的表示形式
- 值得注意的是,C#中的布尔值占用4个字节,C++中占1个字节
NativeContainers
在写Job程序时,除使用Blittable Type类型数据外,还可以用C++上非托管内存堆数据,不过需要依赖另外一个DOTS核心包——Collection中的NativeContainer,以及Unity引擎下为特殊用途,特殊定制的一些容器类型,如 :
- Unity引擎内定义的数组 : NativeArray
- NativeArray的子集 : NativeSlice
- 用于映射访问GameObject,Transform对象的TransformAccess以及TransformAccessArray
- Unity Collections Package
- 可变大小的NativeArray : NativeList
- 单键值对映射表 : NativeHashMap
- 单键多值的 : NativeMultiHashMap
- 先进先出的队列 : NativeQueue
- 支持多线程同时写入的各种数据容器等
- 可自定义的NativeContainers
这些数据容器都是非托管堆上分配的
有DisposeSentinel安全检查来避免内存泄露错误
有AtomicSafetyHandle来追踪所有权与访问权限,避免Race Condition错误
这些类型容器都需要用完手动调用dispose接口进行释放
没有引用返回,会在C#7中支持
Allocation Types
- 这些类型容器在创建时还会涉及分配类型的选择
- 一般最常用的有三种 :
- Persistent : 对应对象的长生命周期内存
- TempJob : 对应在Job中存在的短生命周期内存,4帧以上会收到警告
- Temp : 对应在一个函数内使用的更短生命周期内存
- 这些分配类型在Unity引擎内部分别对应不同的allocator类型