【DOTS学习笔记】从第一个Jobs程序入门

目录

  • 前言
  • Unity Jobs System
  • C# Jobs Systems
  • Blittable Types VS Non-Blittable Types
  • NativeContainers
  • Native Container
  • Allocation Types


前言


本文是Metaverse大衍神君的《DOTS之路》系列课程的学习笔记

Unity Jobs System


  • 包含C# Jobs System 与 C++ Jobs System
  • 利用多核计算平台来简单安全的编写与执行多线程代码
  • 既可以与ECS结合使用也可以单独使用
  • 不需要关系平台CPU核心资源情况

Job System 是通过创建Job任务而非线程来管理多线程代码的
Unity引擎内部会跨多个核心来管理多个线程,以避免上下文的切换

执行时,Job System 会将我们创建的Job任务放到Job队列中以等待执行
工作线程会从Job队列中获取并执行相应的工作

整套系统听起来很简单,但如果我们自己要去实现一套多线程调度框架的话
需要考虑不同的平台、不同的操作系统、不同的硬件核心数、线程调度导致的性能问题等诸多因素
其实是非常复杂且麻烦的

而在Unity下,我们只需要学习C#部分的Job System接口与代码编写规则
而其他方面的工作Unity都帮我们处理好了

目前Unity引擎内部C++的JobSystem部分,需要Untiy引擎源码才可以学习
而C# JobSystem部分Unity提供了C#代码封装后的Job System接口
使用起来也更加简单、直接

虽然C# Job System接口不多,但是分布在

  • UnityEngine.Jobs
  • Unity.Jobs
  • Dots的核心包Collections
  • 等多个地方

本来还有Jobs Package的扩展包
但现在Jobs Package的扩展包已经被移除了
随着DOTS1.0的出现,Job包已经被合并到DOTS1.0的核心包Collections中了
只不过目前还在DOTS的环境包中存在
未来Package Manager中旧不会有它的身影了

另外C# JobSystem的一些旧接口也只是暂时保留
一些新的接口已经开始取代老接口
更多的接口与用法也在不断的添加进来

如果是熟悉以前版本的Job System还需要继续补课

C# Jobs Systems

  • No Race Conditions
    • 只访问数据的拷贝
    • 或者可以转换一段buffer的所有权给这个Job(Native Container)
  • 使用和Unity引擎内C++JobSystem系统的代码
    • 引擎和游戏线程之间没有上下文切换的开销

一般情况下,
在C# Jobs Systems中一般不会引发我们手写多线程程序中出现的Race Conditions问题
原因是在每个Job任务中,只访问数据的拷贝,或是转换一段buffer的所有权给Job任务

另外C# Jobs Systems 实际上使用的就是Unity引擎内C++Job Systems 的代码
所以在引擎与游戏线程之间并没有上下文切换的开销
但毕竟C#与C++下的内存管理与值的类型定义是不同的
所以在写C#Jobs Systems代码时
我们需要区别哪些是Blittable Types类型的数据,哪些类型是 Non-Blittable Types类型的数据

Blittable Types VS Non-Blittable Types

  • Blittable Types:在托管代码和非托管代码的内存中具有相同的表示形式
Blittable Types Non-Blittable Types
System.Byte System.Array
System.SByte System.Boolean
System.Int16 System.Char
System.UInt16 System.Class
System.Int32 System.Object
System.UInt32 System.Mdarray
System.InBt64 System.String
System.IntPtr System.Valuetype
System.UIntPtr System.Szarray

值得一提的是,关注C#下的布尔类型
C#中的布尔值和C++中的布尔值不同
C++中的布尔值占用1个字节,但C#中的布尔值占用4个字节
如果没留意直接使用指针引用的话,程序不会崩溃
但是出现出乎意料的结果,非常难以调试

NativeContainers

  • NativeArray
  • NativeSlice-NativeArray的子集
  • TransformAccess
  • TransformAccessArray
  • Unity Collections Package
    • NativeList-可变大小的NativeArray
    • NativeHashMap-key/value pairs
    • NativeMultiHashMap-单key多值的Pairs
    • NativeQueue-一个FIFO的queue
    • 多线程同时写入版本的NativeHash Map\NativeMultiHashMap\NativeQueue
    • 自定义的Native Containers

我们在写Job程序时,除使用Blittable Types类型数据外还可以使用C++上非托管内存堆数据
不过这里需要依赖另外一个Dots核心包Collections中的NativeContainers
以及Unity引擎下为特殊用途特殊定义的一些容器类型
如Unity引擎内定义的数据——NativeArray
以及数组切片子集NativeSlice
还有用于映射访问gameObject的Transform对象的
TransformAccess和TransformAccessArray
还有Collections包中定义的
可变大小的数组——NativeList
按键值对隐射表——NativeHashMap
单键多值的——NativeMultiHashMap
迁进迁出的Native队列——NativeQueue
支持多线程同时写入的各种数据容器等
除此之外Collections包中还提供了可自定义的NativeContainer接口

Native Container

  • 非托管内存
  • 有DisposeSentinel来避免内存泄漏错误
  • 有AtomicSafetyHandle来追踪所有权与权限
  • 需要手动dispose释放
  • 没有引用返回,会在C#7中支持

Allocation Types

  • Persistent
    • 长生命周期内存
  • TempJob
    • 只在Job中存在的短生命周期,4帧以上会收到警告
  • Temp
    • 一个函数返回前的短生命周期

你可能感兴趣的:(DOTS学习笔记,学习,c#,unity)