Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Nesting NativeArray for ReadOnly job configuration?

Discussion in 'Burst' started by Eckster, Mar 11, 2021.

  1. Eckster

    Eckster

    Joined:
    Feb 9, 2017
    Posts:
    18
    I'm trying to process images, and I'd like to basically be able to pass in a pipeline to my IJobParallelFor and have it run each pixel through the pipeline, with parallelization.

    I have these two structs and the parallel job:

    Code (CSharp):
    1. public struct ImageProcessingStep
    2. {
    3.     [ReadOnly] public NativeArray<ColorReplacement> colorReplacements;
    4.     [ReadOnly] public NativeArray<Color32> textureToApply;
    5. }
    6.  
    7. public struct ColorReplacement
    8. {
    9.     [ReadOnly] public Color32 oldColor;
    10.     [ReadOnly] public Color32 newColor;
    11. }
    12.  
    13.  
    14. [BurstCompile]
    15. public struct ConvertJobParallel : IJobParallelFor
    16. {
    17.     public NativeArray<Color32> output;
    18.     [ReadOnly] public NativeArray<ImageProcessingStep> imageProcessingSteps;
    19.  
    20.     public void Execute(int index)
    21.     {
    22.          ....
    23.      }
    24. }
    25.  

    The idea being that I'll be able to layer textures one by one on top of each other, and I should be able to do this independently per pixel, however, because I can't nest NativeArrays, I'm unable to solve this, although I understand part of the issue is that I can't have dynamically sized elements of a static array.

    What's the best way to send in something like this, where I know it'll be readOnly?
     
    Last edited: Mar 11, 2021
  2. Eckster

    Eckster

    Joined:
    Feb 9, 2017
    Posts:
    18
    In testing I found that it was actually faster to just run the image through multiple jobs than to try to combine everything to run in a single job.

    Much more composable this way, and I think it helps the Burst compiler optimize by ensuring that there's very little branching in the logic it's working on.
     
  3. HellGate94

    HellGate94

    Joined:
    Sep 21, 2017
    Posts:
    132
    i found that IJobParallelFor is almost always slower than spliting work in smaller chunks yourself.

    also if you still need to nest arrays you can do so by using NativeArray<UnsafeList<UnsafeList>> etc
     
  4. Eckster

    Eckster

    Joined:
    Feb 9, 2017
    Posts:
    18
    Do you mean using the IJobChunk type is faster, or do you mean chunking and parallelizing some other way? It seems like the Burst compiler gets me pretty good performance with what I have, but I'm interested if there's a better alternative.
     
  5. HellGate94

    HellGate94

    Joined:
    Sep 21, 2017
    Posts:
    132
    i have not used IJobChunk as of right now. mostly because i'm already working with my own chunks. but if i swap my IJob with for loops to a IJobParallelFor its much slower (guessing due to many more thread syncs)
     
  6. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    This is more of a job system thing - but make sure you set your batch size high enough. the IJobParallelFor will steal work from a central pool in batch-sized chunks, so a higher batch size means it will have to atomically steal less work (which means less thread synchronization).
     
    laurentlavigne likes this.