• Unity2023.1.19_DOTS_JobSystem


    Unity2023.1.19_DOTS_JobSystem

    上篇我们知道了DOTS是包含Entity Component System,Job System,Burst compiler三者的。接下来看下JobSystem的工作原理和具体实现。

    简介:

    官方介绍说:JobSystem允许您编写简单而安全的多线程代码,以便您的应用程序可以使用所有可用的CPU内核来执行代码。也就是说JobSystem是为多线程服务的一个模块。

    JobSystem可以单独使用,但为了提高性能,也还应该使用Burst compiler,Burst compiler是专门为Unity的JobSystem编译而设计的。urst compiler改进了代码生成,从而提高了性能并减少了移动设备上的电池消耗。Burst compiler将在JobSystem之后再关注。

    JobSystem和Burst compiler一起使用的时候,JobSystem工作效果最好。因为Burst不支持托管对象,所以需要使用非托管类型来访问Job中的数据。你可以使用blittable types,或者使用Unity内置的Native container对象,这是一个线程安全的c#本机内存包装器。NativeContainer对象还允许job访问与主线程共享的数据,而不是使用副本。

    ECS为其进行了拓展Unity.Collections命名空间以包含其他类型的 NativeContainer:

    NativeList - 可调整大小的 NativeArray,类似于List
    NativeHashMap - 键/值对,类似于Dictionary
    NativeMultiHashMap - 每个键有多个值。
    NativeQueue - 先进先出队列,类似于Queue

    也可以在ECS中使用JobSystem创建高性能的面向数据代码。

    Collections Package提供可在job和Burst-compiled代码中使用的非托管数据结构。

    Unity使用原生的JobSystem处理原生代码使用多个工作线程,工作线程取决于你应用程序运行设备的CPU核的可用数量。

    通常Unity默认在程序开始时在一个主线程上执行你的代码,你可以使用JobSystem在多个工作线程上执行你的代码,称之为多线程。

    简单代码说明:

    1. using UnityEngine;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. // Job adding two floating point values together
    5. // It implements IJob, uses a NativeArray to get the results of the job, and uses the Execute method with the implementation of the job inside it:
    6. public struct MyJob : IJob
    7. {
    8. public float a;
    9. public float b;
    10. public NativeArray<float> result;
    11. public void Execute()
    12. {
    13. result[0] = a + b;
    14. }
    15. }

    下面的例子建立在MyJob任务上,在主线程上调度一个任务:

    1. using UnityEngine;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. public class MyScheduledJob : MonoBehaviour
    5. {
    6. // Create a native array of a single float to store the result.
    7. // Using a NativeArray is the only way you can get the results of the job, whether you're getting one value or an array of values.
    8. NativeArray<float> result;
    9. // Create a JobHandle for the job
    10. // 给任务创建一个任务处理
    11. JobHandle handle;
    12. // Set up the job
    13. // 创建一个任务
    14. public struct MyJob : IJob
    15. {
    16. public float a;
    17. public float b;
    18. public NativeArray<float> result;
    19. public void Execute()
    20. {
    21. result[0] = a + b;
    22. }
    23. }
    24. // Update is called once per frame
    25. // 每一帧更新
    26. void Update()
    27. {
    28. // Set up the job data 设置任务数据
    29. result = new NativeArray<float>(1, Allocator.TempJob);
    30. MyJob jobData = new MyJob
    31. {
    32. a = 10,
    33. b = 10,
    34. result = result
    35. };
    36. // Schedule the job 安排任务
    37. handle = jobData.Schedule();
    38. }
    39. private void LateUpdate()
    40. {
    41. // Sometime later in the frame, wait for the job to complete before accessing the results.
    42. // 稍后在框架中,等待作业完成后再访问结果。
    43. handle.Complete();
    44. // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
    45. // float aPlusB = result[0];
    46. // Free the memory allocated by the result array
    47. // 释放由结果数组分配的内存
    48. result.Dispose();
    49. }
    50. }

     跟一个测试:

    1. using UnityEngine;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. public class MyScheduledJob : MonoBehaviour
    5. {
    6. // Create a native array of a single float to store the result.
    7. // Using a NativeArray is the only way you can get the results of the job, whether you're getting one value or an array of values.
    8. NativeArray<float> result;
    9. // Create a JobHandle for the job
    10. // 给任务创建一个任务处理
    11. JobHandle handle;
    12. // Set up the job
    13. // 创建一个任务
    14. public struct MyJob : IJob
    15. {
    16. public float a;
    17. public float b;
    18. public NativeArray<float> result;
    19. public void Execute()
    20. {
    21. result[0] = a + b;
    22. }
    23. }
    24. // Update is called once per frame
    25. // 每一帧更新
    26. void Update()
    27. {
    28. // Set up the job data 设置任务数据
    29. result = new NativeArray<float>(1, Allocator.TempJob);
    30. MyJob jobData = new MyJob
    31. {
    32. a = 10,
    33. b = 10,
    34. result = result
    35. };
    36. // Schedule the job 安排任务
    37. handle = jobData.Schedule();
    38. }
    39. private void LateUpdate()
    40. {
    41. // Sometime later in the frame, wait for the job to complete before accessing the results.
    42. // 稍后在框架中,等待作业完成后再访问结果。
    43. handle.Complete();
    44. // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
    45. // float aPlusB = result[0];
    46. // Free the memory allocated by the result array
    47. // 释放由结果数组分配的内存
    48. result.Dispose();
    49. }
    50. }

     

    意思大概是这样了,具体实践具体看!!

    参考文档:

    官方文档

    Unity - Manual: Job system overview (unity3d.com)

    Collections package | Collections | 2.2.1 (unity3d.com)

    Unity - Manual: Thread safe types (unity3d.com)

    这个博主系列的讲到了DOTS,可以看一下:

    DOTS ECS_铸梦xy的博客-CSDN博客

     

  • 相关阅读:
    『 Linux 』 进程间通信概述
    C语言文件操作
    DHCP协议详解
    101道算法JavaScript描述【二叉树】5
    基于算术优化算法优化概率神经网络PNN的分类预测 - 附代码
    mac本地启动sentinel
    (Hexagon_V65_Programmers_Reference_Manual(13)
    随机森林算法
    【NodeJs-5天学习】第一天篇③ —— VsCode上运行第一个NodeJs 程序,配置自动重启插件 nodemon
    Spring Boot项目中热点场景详解(万字总结)
  • 原文地址:https://blog.csdn.net/weixin_45728126/article/details/136468979