Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Trying to understand JobsUtility.Schedule_Injected() in profiler for Burst compiled IJob

Discussion in 'Burst' started by chmodseven, Jun 18, 2019.

  1. chmodseven

    chmodseven

    Joined:
    Jul 20, 2012
    Posts:
    116
    Hi, I am experimenting with speeding up a binary heap using Burst-compiled IJob code for the heapify up/down functions which are normally the bottlenecks in any heap. It does work, and the loop itself is now very fast with Burst, however now the overheard of setting up the job seems to be the new bottleneck:



    For the Push() method, you can see HeapifyUpwardsJob is running very quickly under Burst, however I cannot find any information online regarding the JobsUtility.Schedule_Injected() I'm seeing in the profiler, or why the self cost of that (6.35ms) would be so much more than the job itself (2.87ms).

    Can anyone please explain what these mean, and perhaps any way I could eliminate or reduce those costs. Ideally I would like to avoid using unsafe code - I did try using direct memory reads/writes and it only sped up the job by about 15% and did not change the overheard output seen in the profiler anyway.

    The job struct:

    Code (CSharp):
    1.     [BurstCompile]
    2.     private struct HeapifyUpwardsJob : IJob
    3.     {
    4.         [ReadOnly] public T element;
    5.         [ReadOnly] public int sortComparisonCheck;
    6.         public NativeList<T> heap;
    7.  
    8.         public void Execute ()
    9.         {
    10.             int index = heap.Length;
    11.             heap.Add (element);
    12.             while (index > 0)
    13.             {
    14.                 int parent = (index - 1) >> 1;
    15.                 T valueParent = heap [parent];
    16.                 if (element.CompareTo (valueParent) != sortComparisonCheck)
    17.                 {
    18.                     break;
    19.                 }
    20.  
    21.                 heap [index] = valueParent;
    22.                 heap [parent] = element;
    23.                 index = parent;
    24.             }
    25.         }
    26.     }
    and relevant calling code:

    Code (CSharp):
    1.     private NativeList<T> heap = new NativeList<T> (Allocator.Persistent);
    2.     private HeapifyUpwardsJob heapifyUpwardsJob;
    3.     protected int size;
    4.  
    5.     public BinaryHeapEcs (HeapSortDirection sortDirection = HeapSortDirection.MinHeap)
    6.     {
    7.         int sortComparisonCheck = sortDirection == HeapSortDirection.MinHeap ? -1 : 1;
    8.         heapifyUpwardsJob.sortComparisonCheck = sortComparisonCheck;
    9.         heapifyUpwardsJob.heap = heap;
    10.     }
    11.  
    12.     public void Push (T element)
    13.     {
    14.         heapifyUpwardsJob.element = element;
    15.         heapifyUpwardsJob.Run ();
    16.         size++;
    17.     }
    18.  
    I've used Run() here rather than Schedule() or Execute() as it turned out to be the fastest, and Execute() seems to not use Burst and gives a bunch of getter/setter costs instead:



    So.. any suggestions? :)