认识 Unity C# Job System

一、认识Job System

Unity C# Job System是用于写多线程代码的,使用多线程能够带来高性能,提高code generation的质量,减少移动设备的耗电量等;

二、什么是多线程

在单线程计算机系统中,一次只能同时执行一个指令并只能产生一个结果。加载和完成程序的时间取决于需要CPU要做的任务数量;

而多线程则是为了充分利用CPU通过多核来同时处理多个线程的能力而出现的一种编程类型,任务或命令不再是一个接着一个,而是可以同时进行。

默认情况下有一个线程会在程序开始时运行,就是主线程,主线程创建其它线程处理任务。这些新的线程之间是平行的,而且通常会在完成后向主线程同步它们的结果。

如果有一些任务是需要运行很长时间的(这个时间是指微观上的很长时间,比如IO操作),那么用多线程可以提升性能。然而,游戏开发代码通常在同一时间包含许多小的命令要执行,如果为每一个命令都创建一个线程,那就会创建很多线程,而且每个线程执行很短的时间,而创建线程也是需要消耗的,所以,这种方式会限制CPU和操作系统的能力。

为了减少大量线程频繁创建销毁的问题,我们可以使用线程池来解决这个问题;但是即使有了线程池,也可能会出现大量线程同时激活的问题,如果有多余CPU内核数量的线程存在,就会引起各个线程之间的CPU资源的竞争,从而引起频繁的上下文切换。上下文切换过程会首先保存一个线程的运行状态,然后切换到其它线程,然后切回继续执行,上下文切换是资源密集型操作,应当尽量避免。

什么是CPU密集型、IO密集型:https://zhuanlan.zhihu.com/p/62766037

原生插件和托管插件: https://abaojin.github.io/2017/02/15/unity-plugins/

三、什么是Job System

Job System是一种多线程编程框架,可以理解为何C#提供的多线程模型类似。在job system中,通过创建jobs而不是线程来管理多线程代码,一个作业系统将通过多核来管理一组工作线程,通常会在每个CPU核上有一个工作者线程(为了避免上下文切换)。job system会将jobs放入到作业队列中去执行,作业系统中的工作者线程会从job system中获得job并执行它们。job system会处理作业之间的依赖并确保以一个合适的顺序来执行各个作业。

什么是Job

一个Job是一个很小的工作单元,用于完成一个具体的任务。一个作业接收参数和数据操作,jobs可以是独立的,也可以依赖于其它作业的完成再运行。

什么是Job Dependencies

在复杂系统中,不可能每一个作业都是独立的。一个作业通常会为下一个作业准备数据,如果JobA依赖于JobB,那么Job System就会确保知道JobB完成以后才开始执行JobA。

四、C# Job System的安全性

Race Condition(竞态条件)

多线程代码通常都会有竞态条件的风险,当一个操作的输出取决于其控制之外的另一个进程的时间时,就会出现竞争。竞态条件并非一定是错误,可能是不确定行为的来源。当竞争条件导致错误时,很难查找问题的根源,因为它取决于时间,只能在某些情况下复现。对其进行调试可能会导致问题消失,因为断点和日志记录可能会更改单个线程的时间。因此,竞态条件给多线程编程带来了巨大的挑战。

Safety System(安全系统)

为了简化多线程编程工作,Unity的C#作业系统会检测所有潜在的竞争情况,并减少可能引起的错误的影响。

例如,如果C#作业系统将主线程中的代码数据的引用发送到作业,它无法验证主线程是否在作业写入它的同时正在读取数据,这种情况下就产生了竞态条件。

C# 作业系统通过向每个作业发送需要对其进行操作的数据的副本(而不是引用)来消除这种竞争情况。

C# 作业系统复制数据的方式意味着作业只能访问可复制数据类型,在托管代码和本地代码之间传递时,不需要类型的转换。

C# 作业系统可以使用memcpy复制可复制类型,并且在托管部分和本地部分转换数据。它在计划作业时会通过memcpy将数据放入到本地内存,然后在执行作业时给出托管部分的数据访问权限。

扩展-什么是可复制类型

可复制类型

blittable类型是不需要互操作性封送处理程序特别注意的数据类型,因为默认情况下,它在托管和非托管内存具有通用表示形式。通过将数据固定在内存中,垃圾收集器无法移动,从而可以与非托管应用程序就地共享。这意味着托管代码和非托管代码都将以一致的方式更改这些类型的内存位置,并且封送处理程序需要更少的精力来维护数据完整性。

可复制类型

  • System.Byte
  • System.SByte
  • System.Int16
  • System.UInt16
  • System.Int32
  • System.UInt32
  • System.Int64
  • System.UInt64
  • System.IntPtr
  • System.UIntPtr
  • System.Single
  • System.Double

不可复制类型

  • System.Boolean
  • System.Char
  • System.Object
  • System.String

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章