NativeArray并行数据合并

Posted sifenkesi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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]已经不生效了。

 

  

以上是关于NativeArray并行数据合并的主要内容,如果未能解决你的问题,请参考以下文章

memcpy NativeArray Index to NativeArray Index, Length,怎么办?

如何在 python 中并行化以下代码片段?

float4 的 NativeArray 如何将其中一个 xyzw 设置为循环中的值?

[工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet & FRHICommandListImmediate calls(代码片段

4.3 合并重复的条件执行片段

pandas GroupBy上的方法apply:一般性的“拆分-应用-合并”