Search Unity

  1. Curious about what's going to be in 2020.1? Have a look at the 2020.1 beta blog post.
    Dismiss Notice
  2. Want to see 2020.1b in action? Sign up for our Beta 2020.1 Overview Webinar on April 20th for a live presentation from our evangelists and a Q&A session with guests from R&D.
    Dismiss Notice
  3. Interested in giving us feedback? Join our online research interviews on a broad range of topics and share your insights with us.
    Dismiss Notice
  4. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Allocating a NativeArray in a Job Execute() with Allocator.Temp doesn't work with Burst

Discussion in 'Data Oriented Technology Stack' started by ahmidou, Jan 29, 2019.

  1. ahmidou

    ahmidou

    Joined:
    Sep 17, 2012
    Posts:
    85
    Hi this is a follow up from from a 2018.3 beta post(as the forum section has been locked)
    I sen't a bug about it: Case 1110554
    So basically this improvement in 2018.3:
    is just not working and making an error:
    Can someone confirm I didn't got it wrong?
    Thanks!!

    here's the actual job:
    Code (CSharp):
    1.         [BurstCompile]
    2.         private struct OsdKernel2f : IJobParallelFor
    3.         {
    4.             public int m_SRC_STRIDE;
    5.             public int m_DST_STRIDE;
    6.             public KernelUniformArgs args;
    7.    
    8.             [ReadOnly]
    9.             [NativeDisableContainerSafetyRestriction]
    10.             public NativeArray<int> offsets;
    11.             [ReadOnly]
    12.             [NativeDisableContainerSafetyRestriction]
    13.             public NativeArray<int> sizes;
    14.             [ReadOnly]
    15.             [NativeDisableContainerSafetyRestriction]
    16.             public NativeArray<int> indices;
    17.             [ReadOnly]
    18.             [NativeDisableContainerSafetyRestriction]
    19.             public NativeArray<float> weights;
    20.             [ReadOnly]
    21.             [NativeDisableContainerSafetyRestriction]
    22.             public NativeArray<Vector2> inVertices;
    23.             [NativeDisableParallelForRestriction]
    24.             [NativeDisableContainerSafetyRestriction]
    25.             public NativeArray<float> dstBuffer;
    26.    
    27.             NativeArray<float> readVertex(int index)
    28.             {
    29.                 NativeArray<float> v = new NativeArray<float>(2, Allocator.Temp);
    30.                 int vertexIndex = args.srcOffset + index /* m_SRC_STRIDE*/;
    31.                 for (int i = 0; i < args.length; ++i)
    32.                 {
    33.                     v[i] = inVertices[vertexIndex][i];
    34.                 }
    35.                 return v;
    36.             }
    37.    
    38.    
    39.             void WriteVertexSeparate(int index, NativeArray<float> v, int dstOffset, NativeArray<float> dstVertexBuffer)
    40.             {
    41.                 int vertexIndex = dstOffset + index * m_DST_STRIDE;
    42.                 for (int i = 0; i < args.length; ++i)
    43.                 {
    44.                     dstVertexBuffer[vertexIndex + i] = v[i];
    45.                 }
    46.             }
    47.    
    48.             void AddWithWeight(ref NativeArray<float> v, NativeArray<float> src, float weight)
    49.             {
    50.                 for (int i = 0; i < args.length; ++i)
    51.                 {
    52.                     v[i] += weight * src[i];
    53.                 }
    54.             }
    55.    
    56.             public void Execute(int i)
    57.             {
    58.                 int current = i + args.batchStart;
    59.    
    60.                 if (current >= args.batchEnd)
    61.                 {
    62.                     return;
    63.                 }
    64.                 NativeArray<float> dst = new NativeArray<float>(2, Allocator.Temp);
    65.    
    66.                 int offset = offsets[current],
    67.                     size = sizes[current];
    68.    
    69.                 for (int j = 0; j < size; j++)
    70.                 {
    71.                     AddWithWeight(ref dst, readVertex(indices[offset + j]), weights[offset + j]);
    72.                 }
    73.    
    74.                 WriteVertexSeparate(current, dst, args.dstOffset, dstBuffer);
    75.             }
    76.         }
    77.  
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    2,061
    I think this is only meant to be supported in 2019.1
     
  3. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    220
    Funny thing is upgrading Unity would solve one Burst compilation error and encounter the next when allocating native containers. 2018.3.2 had a divide by zero error. 2018.3.3 had the null reference. 2019.1a did not support the itor operation. 2019.1b might have solved it - if not, we'll be forced to wait for the full release.
     
  4. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    133
    As tertle had said, Temp allocation in jobs only work in 2019.1 and onward. Anything related to Allocators and NativeArray (other NativeContainers are separated) needs an editor update.

    For your case, maybe you can use stackalloc if you are willing to use unsafe code.

    []'s
     
  5. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    220
    Just tested with 2019.1b, Temp allocation in jobs still doesn't work. Error message now says that the
    ldind.ref instruction is not supported. Looks like the Unity team is adding support for Temp allocation step by step
     
  6. whiskers434

    whiskers434

    Joined:
    Sep 23, 2014
    Posts:
    22
    was this ever fixed and in what version? was it back ported to 2018 LTS?
     
  7. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    2,061
    Nothing will be back ported to 2018.x
    Latest entities requires 2019.3 and won't be back ported either.
     
  8. whiskers434

    whiskers434

    Joined:
    Sep 23, 2014
    Posts:
    22
    cheers, will wait out for 2019 LTS
     
  9. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    738
    Use stackalloc with NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray method. Temp allocations are harmful for job performance.
     
  10. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    2,061
    It's not that bad if you avoid doing them per entity. I consider an allocation per chunk and re-using them (or some other type of grouping) acceptable for most practices.
     
  11. wobes

    wobes

    Joined:
    Mar 9, 2013
    Posts:
    738
    I tried 1k stackallocs vs 1k Temp allocations over 7 worker threads. The profiler with Temp allocations was full of overhead.
    Slash I am sure stackalloc memory would be faster than Temp.
     
    Last edited: Dec 29, 2019
  12. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    2,061
    Yeah 1k allocations is huge.

    I've made a post about this in the past here: https://forum.unity.com/threads/tip-avoid-allocating-per-entity.726275/

    about how I write custom jobs to group allocations which doubled the performance of jobs.
     
unityunity