zoukankan      html  css  js  c++  java
  • 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]已经不生效了。

      

  • 相关阅读:
    codechef Dynamic GCD [树链剖分 gcd]
    bzoj 4546: codechef XRQRS [可持久化Trie]
    bzoj 4835: 遗忘之树 [树形DP]
    bzoj 4033: [HAOI2015]树上染色 [树形DP]
    bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]
    3167: [Heoi2013]Sao [树形DP]
    bzoj 3812: 主旋律 [容斥原理 状压DP]
    有标号的二分图计数 [生成函数 多项式]
    有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
    BZOJ 3028: 食物 [生成函数 隔板法 | 广义二项式定理]
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/12445981.html
Copyright © 2011-2022 走看看