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