NativeArray數據並行寫入


按照一般的寫法,write會產生race condition,所以需要通過依賴關系按順序執行:

using UnityEngine;
using Unity.Jobs;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;

public struct WritePartOfArrayJob : IJobParallelFor
{
    [ReadOnly]
    public NativeArray<float> source;
    [NativeDisableContainerSafetyRestriction] public NativeArray<float> dest;
    public int startIndex;

    public void Execute(int index)
    {
        int idx = startIndex + index;
        dest[idx] = source[index];
    }
}

public class Job_CombineWriting : MonoBehaviour
{
    private void Start()
    {
        NativeArray<float> array1 = new NativeArray<float>(5, Allocator.TempJob);
        NativeArray<float> array2 = new NativeArray<float>(5, Allocator.TempJob);
        for (int i = 0; i < 5; ++i)
        {
            array1[i] = i;
            array2[i] = i + 5;
        }

        NativeArray<float> arrayCombine = new NativeArray<float>(10, Allocator.TempJob);
        WritePartOfArrayJob job1 = new WritePartOfArrayJob()
        {
            source = array1,
            dest = arrayCombine,
            startIndex = 0,
        };
        JobHandle handle1 = job1.Schedule(array1.Length, 1);

        WritePartOfArrayJob job2 = new WritePartOfArrayJob()
        {
            source = array2,
            dest = arrayCombine,
            startIndex = 5,
        };
        JobHandle handle2 = job2.Schedule(array2.Length, 1, handle1);
        handle2.Complete();

        for(int i = 0; i < arrayCombine.Length; ++i)
        {
            Debug.Log(arrayCombine[i]);
        } 

        array1.Dispose();
        array2.Dispose();
        arrayCombine.Dispose();
    }
}

  job2,在schedule的時候會依賴job1,這樣就不會產生沖突。

  但是也可以通過如下方法並行執行,分別寫入目標array的不同索引范圍:

        NativeArray<float> arrayCombine = new NativeArray<float>(10, Allocator.TempJob);
        NativeArray<JobHandle> handles = new NativeArray<JobHandle>(2, Allocator.TempJob);
        WritePartOfArrayJob job1 = new WritePartOfArrayJob()
        {
            source = array1,
            dest = arrayCombine,
            startIndex = 0,
        };
        handles[0] = job1.Schedule(array1.Length, 1);

        WritePartOfArrayJob job2 = new WritePartOfArrayJob()
        {
            source = array2,
            dest = arrayCombine,
            startIndex = 5,
        };
        handles[1] = job2.Schedule(array2.Length, 1);
        JobHandle.CompleteAll(handles);

  這個用法的關鍵在於給write的NativeArray設置屬性:[NativeDisableContainerSafetyRestriction]。

  這個屬性可以用來禁用job的 safety system,讓你對NativeArray擁有完全的控制權,同時系統也就不會幫你定位race condition等情況,所以在使用的時候,需要自己確保安全性。

  ps:舊的用法[NativeDisableParallelForRestriction]已經不生效了。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM