当前位置: 首页 > article >正文

【Unity3D】ECS入门学习(十二)IJob、IJobFor、IJobParallelFor

        IJob:开启单个线程进行计算,线程内不允许对同一个数据进行操作,也就是如果你想用多个IJob分别计算,将其结果存储到同一个NativeArray<int>数组是不允许的,所以不要这样做,如下例子就是反面教材,应该直接用一个IJob去进行for循环,将结果存储到传入的NativeArray<int>。

using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;

public class MyJob : MonoBehaviour
{
    //public List<int> intArray;
    //public void Start()
    //{
    //    intArray = new List<int>();
    //    for (int i = 0; i < 100; i++)
    //    {
    //        for (int j = 0; j < 100; j++)
    //        {
    //            intArray.Add(i * j);
    //        }
    //    }
    //}

    void Start()
    {
        List<NativeArray<int>> map = new List<NativeArray<int>>();
        NativeArray<int> tempArray = new NativeArray<int>(10000, Allocator.TempJob);
        //处理多个Job时需要缓存JobHandle for之外执行Complete,单个时可以直接 jobHandle.Complete(); 
        NativeList<JobHandle> jobHandles = new NativeList<JobHandle>(Allocator.Temp);
        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 100; j++)
            {
                map.Add(new NativeArray<int>(1, Allocator.TempJob));
                SingleJob singleJob = new SingleJob() { i = i, j = j, result = map[i * 100 + j] };
                JobHandle jobHandle = singleJob.Schedule();
                jobHandles.Add(jobHandle);
            }
        }
        JobHandle.CompleteAll(jobHandles);

        Debug.Log(map[20 * 100 + 30][0]);

        jobHandles.Dispose();
        tempArray.Dispose();
        foreach (var v in map)
        {
            v.Dispose();
        }
        map.Clear();
    }

    [BurstCompile]
    public struct SingleJob : IJob
    {
        public int i, j;
        public NativeArray<int> result;
        public void Execute()
        {
            result[0] = i * j;
        }
    }
}

IJobParallelFor:进行并行计算移动物体的位置信息(帧数在35左右)

using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;

public class MyJob : MonoBehaviour
{
    public GameObject cubePrefab;
    public List<Transform> cubeTransList;
    public float time;
    public int dir = 1;

    void Start()
    {
        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 100; j++)
            {
                GameObject go = GameObject.Instantiate(cubePrefab);
                go.transform.position = new Vector3(i * 2, j * 2, 0);
                cubeTransList.Add(go.transform);
            }
        }
    }
    void Update()
    {
        MyJobParallelFor myJobParallelFor = new MyJobParallelFor();
        NativeArray<float3> float3sArray = new NativeArray<float3>(cubeTransList.Count, Allocator.TempJob);

        for (int i = 0; i < cubeTransList.Count; i++)
        {
            float3sArray[i] = cubeTransList[i].transform.localPosition;
        }

        myJobParallelFor.float3sArray = float3sArray;
        myJobParallelFor.deltaTime = Time.deltaTime;

        time += Time.deltaTime;
        if (time >= 2)
        {
            dir = dir * -1;
            time = 0;
        }
        myJobParallelFor.dir = dir;

        JobHandle jobHandle = myJobParallelFor.Schedule(cubeTransList.Count, 10); //10是内核数 (最大会使用到实际CPU内核数)
        jobHandle.Complete();

        for (int i = 0; i < cubeTransList.Count; i++)
        {
            cubeTransList[i].localPosition = float3sArray[i];
        }
        float3sArray.Dispose();
    }

    //并行执行线程
    [BurstCompile]
    public struct MyJobParallelFor : IJobParallelFor
    {
        public NativeArray<float3> float3sArray;
        public float deltaTime;
        public int dir;
        //index对应执行传入的数组索引
        public void Execute(int index)
        {
            float3sArray[index] += new float3(0, dir * deltaTime, 0);
        }
    }
}

若不想使用并行,可以使用IJobFor(并发计算)需修改为如下:

JobHandle jobHandle = default;
jobHandle = myJobParallelFor.Schedule(cubeTransList.Count, jobHandle);
jobHandle.Complete();

 或者并发与并行兼容的,允许并行操作情况下才会进行并行。

JobHandle jobHandle = default;
jobHandle = myJobParallelFor.ScheduleParallel(cubeTransList.Count, 10, jobHandle); //10是内核数 (最大会使用到实际CPU内核数)
jobHandle.Complete();

http://www.kler.cn/a/459116.html

相关文章:

  • 如何轻松关闭 iPhone 上的 HEIC [HEIC 图像技巧]
  • docker中使用Volume完成数据共享
  • UE5失真材质
  • Swift Combine 学习(五):Backpressure和 Scheduler
  • Eplan 布局图中的宏/设备/安装板比例缩放
  • 拟声 0.60.0 | 拟态风格音乐播放器,支持B站音乐免费播放
  • 复合机器人CNC铝块自动化上下料技术替代人工完成作业
  • 电脑开机后进不了系统如何修复?原因及解决步骤介绍
  • 利用Abel_Cain软件实现ARP欺骗
  • 基于 SensitiveWordBs 实现敏感词过滤功能
  • 微信小程序:正确输出<小于,大于>符号
  • !倒序数 !
  • 算法每日双题精讲 —— 滑动窗口(水果成篮,找到字符串中所有字母异位词)
  • 旧衣回收小程序开发,绿色生活,便捷回收
  • PyQt的介绍
  • jvm-基础篇
  • docker中使用nginx
  • uniapp通过v-if进行判断时,会出现闪屏?【已解决】
  • 在docker中对MySQL快速部署与初始数据
  • 游戏引擎学习第67天
  • Claude 官方发布《构建高效的 Agents 指南》全文翻译版,附中英文 PDF 下载
  • 一个最简单的ios程序(object_c)的编写
  • 2024年中国新能源汽车用车发展怎么样 PaperGPT(二)
  • 基于Oauth2的SSO单点登录---后端
  • C++ 设计模式:原型模式(Prototype Pattern)
  • Slate文档编辑器-Decorator装饰器渲染调度