自学内容网 自学内容网

【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();

原文地址:https://blog.csdn.net/qq_39574690/article/details/144803985

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!