Search Unity

[Job System, Example] Starting with simple optimizations : Using a NativeArray<struct> ?

Discussion in 'C# Job System' started by Quatum1000, Jul 15, 2018.

  1. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi everyone,

    Compile a Job with the burst compiler

    To start with simple optimizations i followed this small tutorial.
    https://docs.unity3d.com/Packages/com.unity.burst@0.2/manual/index.html#standalone-player-support

    This simple example in the docs use a native array to run a job over the NativeArray<float>. That works fine.
    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. using UnityEngine;
    5.  
    6. public class MyBurst2Behavior : MonoBehaviour
    7. {
    8.     void Start()
    9.     {
    10.         var input = new NativeArray<float>(10, Allocator.Persistent);
    11.         var output = new NativeArray<float>(1, Allocator.Persistent);
    12.         for (int i = 0; i < input.Length; i++) input[i] = 1.0f * i;
    13.  
    14.         var job = new MyJob
    15.         {
    16.             Input = input,
    17.             Output = output
    18.         };
    19.         job.Schedule().Complete();
    20.  
    21.         Debug.Log("The result of the sum is: " + output[0]);
    22.         input.Dispose();  output.Dispose();
    23.     }
    24.  
    25.     [BurstCompile(CompileSynchronously = true)]
    26.     private struct MyJob : IJob
    27.     {
    28.         [ReadOnly]
    29.         public NativeArray<float> Input;
    30.  
    31.         [WriteOnly]
    32.         public NativeArray<float> Output;
    33.  
    34.         public void Execute()
    35.         {
    36.             float result = 0.0f;
    37.             for (int i = 0; i < Input.Length; i++)
    38.             {
    39.                 result += Input[i];
    40.             }
    41.             Output[0] = result;
    42.         }
    43.     }
    44. }
    But how to use NativeArray<struct>. in this case?
    • Struct types
    • Burst supports regular structs with any field with supported types.
    This following example use a NativeArray<struct> instead of NativeArray<float>

    Code (CSharp):
    1. using System;
    2. using Unity.Burst;
    3. using Unity.Collections;
    4. using Unity.Jobs;
    5. using UnityEngine;
    6. using Unity.Entities;
    7.  
    8. public class Test_NativeArrayStruct : MonoBehaviour {
    9.  
    10.     [Serializable]
    11.     public struct theStruct {
    12.         public int int1;
    13.     }
    14.  
    15.     public NativeArray<theStruct> structNative = new NativeArray<theStruct>();
    16.  
    17.     private void Awake() {
    18.         structNative = new NativeArray<theStruct>(10000, Allocator.Persistent);
    19.     }
    20.  
    21.     private void Update() {
    22.         var job = new MyJob {
    23.             StructNative = structNative, // <------------ Fail ---------------
    24.         };
    25.         job.Schedule().Complete();
    26.     }
    27.  
    28.     [BurstCompile(CompileSynchronously = true)]
    29.     private struct MyJob : IJob {
    30.  
    31.         public theStruct[] StructNative;
    32.         public void Execute() {
    33.  
    34.             for (int i = 0; i < StructNative.Length; i++) {
    35.                 StructNative[i].int1 = 77;
    36.             }
    37.         }
    38.     }
    39.  
    40.     private void OnDestroy() {
    41.         structNative.Dispose();
    42.     }
    43. }
    44.  


    But it fail with the data conversion message:

    StructNative = structNative,
    Untitled-1.jpg


    Any ideas how this can be solved?
     
    Last edited: Jul 15, 2018
  2. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    Code (CSharp):
    1.     ....
    2.     private struct MyJob : IJob {
    3.         public NativeArray<theStruct> StructNative;
    4.         ....
     
  3. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Thanks I over read it. -)

    Unfortunately it cause "fail access because its not a variable error"

    Code (csharp):
    1. for (int i = 0; i < StructNative.Length; i++) {
    2.                     StructNative[I].int1 = 77; // <--------------
    3.     }
     
    Last edited: Jul 15, 2018
  4. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    yeah to edit component data you should do the following:

    Code (CSharp):
    1. // get a copy of the data
    2. var data = StructNative[i];
    3. // do manipulations to the copy of the data
    4. data.Int1 = 77;
    5. // overwrite the existing data inside the StructNative array
    6. StructNative[i] = data;
    7.  
     
    Quatum1000 likes this.
  5. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Seems that works for the code but not for the compiler. Simply crash mono in this case.. :-O
     
    Last edited: Jul 15, 2018
  6. mike_acton

    mike_acton

    Unity Technologies

    Joined:
    Nov 21, 2017
    Posts:
    110
    Code (CSharp):
    1. StructNative[i] = new theStruct { Int1 = 77 };
     
  7. dousi96

    dousi96

    Joined:
    Jul 28, 2014
    Posts:
    23
    @mike_acton is correct to use a struct to encapsulate native arrays?

    Right now i'm working on a Ear Clipping triangulator and I want to create something like this:

    Code (CSharp):
    1.     public struct PolygonJobData : IDisposable
    2.     {
    3.         [ReadOnly]
    4.         public NativeArray<float2> Vertices;
    5.         [ReadOnly]
    6.         public int NumContournPoints;
    7.         [ReadOnly]
    8.         public NativeArray<int> StartPointsHoles;
    9.         [ReadOnly]
    10.         public NativeArray<int> NumPointsPerHole;
    11.  
    12.         public PolygonJobData (Vector2[] contourn, Vector2[][]holes, Allocator allocator)
    13.         {
    14.             ...
    15.         }
    16.  
    17.         public void Dispose()
    18.         {
    19.             ...
    20.         }
    21.     }
     
  8. Alex-Naronov

    Alex-Naronov

    Joined:
    Jun 6, 2017
    Posts:
    6
    Hi, dousi96. Did you manage to create an NativeArray with your PolygonJobData structure? I have the similar structure, but I can't create NativeArray, here is topic with my problem https://forum.unity.com/threads/job...t-types-error-invalidoperationexcepti.988558/ If you have any ideas, I will be very grateful