Version: 6000.3
语言: 中文
使用作业系统编写多线程代码
作业概述

作业系统概述

Unity 的作业系统允许您创建多线程代码,以便您的应用程序可以使用所有可用的 CPU 内核来执行您的代码。这提供了更高的性能,因为您的应用程序更有效地使用它运行的所有 CPU 内核的容量,而不是在一个 CPU 内核上运行所有代码。

您可以单独使用作业系统,但为了提高性能,还应该使用 Burst 编译器,该编译器专门设计用于为 Unity 的作业系统编译作业。Burst 编译器改进了代码生成,从而提高了移动设备的性能并减少了电池消耗。

您还可以将作业系统与 Unity 的实体组件系统一起使用,以创建高性能的面向数据的代码。

多线程

Unity 使用自己的原生作业系统通过多个工作线程处理自己的原生代码,这些线程取决于运行应用程序的设备上可用的 CPU 内核数量。通常,Unity 在一个默认在程序开始时运行的线程上执行您的代码,称为主线程。但是,当您使用作业系统时,Unity 会通过工作线程执行您的代码,这称为多线程。

多线程利用 CPU 跨多个内核同时处理大量线程的能力。它们不是一个接一个地执行任务或指令,而是同时运行。工作线程彼此并行运行,并在完成后将其结果与主线程同步。

作业系统确保只有足够的线程来匹配 CPU 内核的容量,这意味着您可以根据需要安排任意数量的任务,而无需特别知道有多少个可用的 CPU 内核。这与其他依赖线程池等技术的作业系统不同,在线程池中,比 CPU 内核更容易低效地创建更多的线程。

偷工

作业系统使用工作窃取作为其调度策略的一部分,以平衡跨工作线程共享的任务量。工作线程处理任务的速度可能比其他线程快,因此,一旦工作线程处理完其所有任务,它就会查看其他工作线程的队列,然后处理分配给另一个工作线程的任务。

安全系统

为了更轻松地编写多线程代码,作业系统有一个安全系统,可以检测所有潜在的竞争条件并保护您免受它们可能导致的错误的影响。当一个作的输出取决于另一个进程超出其控制范围的时序时,就会发生竞争条件。

例如,如果作业系统将主线程中代码中的数据引用发送到作业,则无法验证主线程是否在作业写入数据的同时读取数据。此方案会创建争用条件。

为了解决这个问题,作业系统向每个作业发送它需要作的数据的副本,而不是对主线程中数据的引用。此副本隔离数据,从而消除争用条件。

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

作业系统使用 memcpy 复制 blittable 类型并在 Unity 的托管部分和本机部分之间传输数据。它在调度作业时使用 memcpy 将数据放入本机内存中,并在执行作业时让托管端访问该副本。有关详细信息,请参阅计划作业

收藏包

除了核心 Unity 引擎中提供的作业系统外,Collections 包还扩展了许多作业类型本机容器。有关详细信息,请参阅集合文档

其他资源

使用作业系统编写多线程代码
作业概述