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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Local arrays- how?

Discussion in 'Entity Component System' started by PlayingPolicy, Sep 18, 2018.

  1. PlayingPolicy

    PlayingPolicy

    Joined:
    Dec 20, 2013
    Posts:
    15
    An algorithm I'm trying to implement requires lots of reading and writing of a "local" array, per invocation of IJobParallelFor.Execute().

    Local arrays are strict enough requirement that this is the only reason I'm not writing it for the GPU. The back of the napkin tells me the algorithm will take ~10 minutes to execute on my CPU, under the assumption of local arrays being part of the implementation. Without them, performance will plummet, and implementation complexity will skyrocket. So please take my word for it that there's no other sensible way to proceed.

    I've run into this pattern in parallel programming before. With C# threads, I'd make a "worker" class for the job, which pre-allocates any resources needed for execution, such as arrays. In C++, I'd probably be lazy and allocate a big stack array. But how do I do it in Unity's job system?
     
  2. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    558
    in 2018.3 you can try to crate a Temp NativeArray inside the job Execute, as they removed the DisposeSentinel for Temp allocator.

    or, you can allocate a single array, pass it to the job as
    [NativeDisableParallelForRestriction]
    , and in the job you fetch a slice of it with
    bigArray.Slice(index * count, count)
    where count is how many elements per iteration you need.
     
  3. dartriminis

    dartriminis

    Joined:
    Feb 3, 2017
    Posts:
    157
    The Unity team are planning on making NativeArrays temp allocatable inside jobs (Link).
     
  4. PlayingPolicy

    PlayingPolicy

    Joined:
    Dec 20, 2013
    Posts:
    15
    Thanks guys.

    In my case, there will be (minimally) about 7,000,000 invocations of IJobParallelFor.Execute(), each one doing all this array malarkey. Versus the alternatives in other programming models I mentioned, there is clearly more allocation overhead. It's likely it's still fine, since there shouldn't be much contention between threads for allocation at any moment, but just how cheap is the new allocator? Even if not the worst thing, it does seem absurd for a thread to allocate an array, chuck it a fraction of a second later, then allocate a brand new array of the exact same size afterward.

    The bigger concern with this solution is de-allocation. Some allocators designed for games only de-allocate at the frame granularity. If Unity's is like that, it would cause massive over-allocation in my case.


    Something like this was appealing, but if it's tied to IJobParallelFor, it severely restricts how much work I can schedule at once. If I schedule it all, memory consumption could shoot up as high as 21 GB. That's not an option, so I'd have to arbitrarily cut up the work just to save memory due to gaps in the API, which isn't ideal either. If I could just access a unique thread ID, it would be trivial to implement pseudo-thread-local-storage.
     
  5. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    ThreadIndex can be injected into Job structure. Quick test seems to confirm that it even works for IJobParallelFor but I didn't use it really:
    Code (CSharp):
    1. [NativeSetThreadIndex] public int threadIndex;
     
  6. PlayingPolicy

    PlayingPolicy

    Joined:
    Dec 20, 2013
    Posts:
    15
    ^ Thanks. That's the final piece of the puzzle.
     
  7. PlayingPolicy

    PlayingPolicy

    Joined:
    Dec 20, 2013
    Posts:
    15
    Important addendum for anyone finding this in the future:

    Code (CSharp):
    1. [NativeSetThreadIndex]
    is defined in
    Code (CSharp):
    1. Unity.Collections.LowLevel.Unsafe