Search Unity

Resolved how to queue a main thread function call from inside a job?

Discussion in 'Entity Component System' started by RamblingRoot, Jul 11, 2021.

  1. RamblingRoot

    RamblingRoot

    Joined:
    Apr 2, 2020
    Posts:
    24
    When certain conditions are met within a job system, I need to call a function on the main thread (the function will also require some input variables from within the job system). This can be done after the job system has completed. So I guess I'm trying to find a way to have a sort of main-thread function call queue that I can add to from inside the job system and then loop through and make each function call on the main thread after the job system has finished.

    An example to help clarify what I'm trying to do:
    I have a multithreaded job system that updates temperature on a 2d grid of entities. For any (x,y) position on the grid where temperature < 100, I need to call AddIceBlock(int xPosition, int yPosition) on the main thread. I want to avoid looping through each (x,y) position/entity to check temperature on the main thread for efficiency (just assume this will be too slow for the example).

    I had the thought to use a native hashset to add the required inputs for each function call, making this data available as a public variable and then using it to call the desired function on the main thread. However, native hashsets are not able to achieve this due to limitations with the burst compiler and multithread safety from what I can tell.

    Also, not sure if this will matter, but each function call will always have unique inputs (no chance of multiple threads needing to call the same function with same inputs)

    I'm not super knowledgeable yet on what is possible with ECS/DOTS, i'm looking for an efficient solution that I'm guessing exists, but I'm unable to find through researching (so far)

    Thanks!
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    I think you want NativeQueue.ParallelWriter. Keep in mind that doing things this way is non-deterministic. If you want things to be deterministic, see if using Schedule instead of ScheduleParallel and NativeQueue (non-ParallelWriter) is good enough performance for you.
     
  3. RamblingRoot

    RamblingRoot

    Joined:
    Apr 2, 2020
    Posts:
    24
    thanks for the tips, no idea how to use nativequeue yet, but i'm looking into it now, looks promising. Why would using parallelwriter be non-deterministic?
     
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Because the order events are added to the queue are dependent on the order the worker threads get to batches.
     
  5. RamblingRoot

    RamblingRoot

    Joined:
    Apr 2, 2020
    Posts:
    24
    got it, sorry lots of new concepts for me with multithreading. Order doesn't matter for my case, so parallelwriter should work fine.
     
  6. RamblingRoot

    RamblingRoot

    Joined:
    Apr 2, 2020
    Posts:
    24
    So, I coded in a nativequeue<(int, int, byte)>.ParallelWriter container and am using enqueue() to add data to the queue from inside the job. But I'm having issues figuring out how to access the data in the queue from the main thread. Could you give me an example on how I might loop through each entry in the queue? I feel like there is a step I'm missing as parallelwriter does not have a dequeue(), do I have to convert to a different container first?
     
  7. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    You use the NativeQueue that you created the ParallelWriter from.
     
  8. RamblingRoot

    RamblingRoot

    Joined:
    Apr 2, 2020
    Posts:
    24
    Yep, figure it out. Thanks for the help!