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

Feedback Could we have the PLUS operator defined on JobHandle to act like CombineDependencies?

Discussion in 'Entity Component System' started by SamOld, Jul 7, 2020.

  1. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    Could we have the PLUS operator defined for
    JobHandle
    to act like
    CombineDependencies
    ? I quite often wish to accumulate handles and it can be quite cumbersome.

    Here's a real piece of code from a project.

    Code (CSharp):
    1. var handle = new FlushForwardDependenciesJob()
    2. {
    3.     DependencyPairsQueue = this.dependencyPairsQueue,
    4.     ForwardDependenciesMap = this.forwardDependenciesMap
    5. }.Schedule(this.forwardDependenciesHandle);
    6.  
    7. this.forwardDependenciesHandle = JobHandle.CombineDependencies(this.forwardDependenciesHandle, handle);
    Here's an attempt to inline the handle combination.

    Code (CSharp):
    1. this.forwardDependenciesHandle = JobHandle.CombineDependencies(
    2.     this.forwardDependenciesHandle,
    3.     new FlushForwardDependenciesJob()
    4.     {
    5.         DependencyPairsQueue = this.dependencyPairsQueue,
    6.         ForwardDependenciesMap = this.forwardDependenciesMap
    7.     }.Schedule(this.forwardDependenciesHandle)
    8. );
    Here's a way that uses a custom extension method to try to make things slightly neater.

    Code (CSharp):
    1. public static void CombineInPlace(ref this JobHandle job0, JobHandle job1) => job0 = JobHandle.CombineDependencies(job0, job1);
    2.  
    3. this.forwardDependenciesHandle.CombineInPlace(
    4.     new FlushForwardDependenciesJob()
    5.     {
    6.         DependencyPairsQueue = this.dependencyPairsQueue,
    7.         ForwardDependenciesMap = this.forwardDependenciesMap
    8.     }.Schedule(this.forwardDependenciesHandle)
    9. );
    And here's how this could be written if the operator were provided. Obviously the difference isn't large, but I find it significantly neater, and it's often small details like this which make an API nice.

    Code (CSharp):
    1. this.forwardDependenciesHandle += new FlushForwardDependenciesJob()
    2. {
    3.     DependencyPairsQueue = this.dependencyPairsQueue,
    4.     ForwardDependenciesMap = this.forwardDependenciesMap
    5. }.Schedule(this.forwardDependenciesHandle);
    Of course this could also be used when combining dependencies in
    Schedule
    calls. I find
    .Schedule(this.forwardDependenciesHandle + this.backwardDependenciesHandle)
    to be significantly neater than
    .Schedule(JobHandle.CombineDependencies(this.forwardDependenciesHandle, this.backwardDependenciesHandle))
     
    Last edited: Jul 7, 2020
  2. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    Because
    JobHandle.CombineDependencies
    only has overloads for 2 and 3 handles, I just had to write the following, which I think is a bit silly.

    Code (CSharp):
    1.  
    2. var deps = JobHandle.CombineDependencies(
    3.     this.uniqueCollectionHandle,
    4.     JobHandle.CombineDependencies(this.forwardDependenciesHandle, this.backwardDependenciesHandle, this.fullCollectionHandle)
    5. );
    6.  
    There are other ways I can write this, which are perhaps a little neater, but still require multiple calls to the method with the long verbose name and the naming of intermediate variables.

    Code (CSharp):
    1.  
    2. var directionalDeps = JobHandle.CombineDependencies(this.forwardDependenciesHandle, this.backwardDependenciesHandle);
    3. var collectionDeps = JobHandle.CombineDependencies(this.uniqueCollectionHandle, this.fullCollectionHandle);
    4. var deps = JobHandle.CombineDependencies(directionalDeps, collectionDeps);
    Or I can inline it like this:

    Code (CSharp):
    1.  
    2. var deps = JobHandle.CombineDependencies(
    3.     JobHandle.CombineDependencies(this.forwardDependenciesHandle, this.backwardDependenciesHandle),
    4.     JobHandle.CombineDependencies(this.uniqueCollectionHandle, this.fullCollectionHandle)
    5. );
    Compare and contrast with the proposed PLUS operator version which fits on one line with no nesting or intermediate variables.

    Code (CSharp):
    1. var deps = this.forwardDependenciesHandle + this.backwardDependenciesHandle + this.uniqueCollectionHandle + this.fullCollectionHandle;
    I know that tagging the CTO is probably considered cheeky, but @Joachim_Ante. I've just realised that this thread received quite a lot of support in likes, so I'd just like to be sure that somebody from Unity has at least seen it.
     
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Its important that the actual combining of job dependencies happens in one batched call for performance. Thats why we have an array version. I agree we should also expose a couple extra overloads with 3/4/5/6 combines.

    I don't know how we could make this work with with + operator in C#.
     
  4. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    Please, could you provide a
    CombineDependencies(params JobHandle[] handles)
    variant because it's really inconvenient to have to allocate, fill, and dispose native arrays for tiny menial things or when dependencies become more numerous than the overloads one has at their disposal. :)

    From a usability standpoint, this focus on overloads clutters code completion pretty badly in Rider. (admittedly I can't imagine it getting any worse than Entities.ForEach...).

    upload_2020-7-15_14-14-45.png
     
    Last edited: Jul 15, 2020
    Nyanpas likes this.
  5. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    Interesting. I hadn't considered that it would be expensive enough to matter compared to everything else going on.

    So performance would be the same when only combining two, which is a common scenario. This would be completely fine in the case of
    +=
    accumulation. It would be slightly worse than
    JobHandle.CombineDependencies
    when combining more.

    Unless the cost is alarmingly higher than I've intuited, I would personally be happy with the operator being provided and a documentation note saying to use
    JobHandle.CombineDependencies
    if you're doing more than 2 and need the absolute fastest speed. Perhaps that violates your Performance By Default design principles.

    I've personally written code that does accumulation like this, just for neatness. Obviously according to what you've said here, this is slower, but it was the direction that I felt the current API pushed me in for neatness. Maybe that's only me and I should change that habit, but I do wonder whether others have also been writing in this style. If they have, then it's not truly fast by default.

    deps = JobHandle.CombineDependencies(deps, additionalHandle1);
    deps = JobHandle.CombineDependencies(deps, additionalHandle2);



    We have IL rewriting in play here. Could you transform an operator chain into a single
    JobHandle.CombineDependencies
    call? I've only ever done that type of compile time transformation at the Roslyn level and not with IL, but it sounds simple enough.

    If none of the above are acceptable, could we at least have a shorter version of the current API? Maybe
    new JobHandle(dep0, dep1, dep2)
    . Just removing the clutter of the long method name would be a step in the right direction.
     
    Last edited: Jul 15, 2020
    jdtec likes this.
  6. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    I haven't had a problem in Visual Studio. That sounds like an issue to take up with Rider. Using
    params
    with a managed array creates garbage, which is not something that should be happening in DOTS.

    There's an open and well liked C# proposal to add
    params Span<T>
    support to the language, which would allow zero allocation
    params
    usage. That idea's been being thrown around since at least as far back as 2017 and is currently listed as a "soon candidate", so we'll probably get it one day, but it won't be for a while unfortunately.
     
    yondercode likes this.
  7. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    939
    You can already do something like :
    Code (CSharp):
    1.         JobHandle.CombineDependencies(new NativeArray<JobHandle>(new JobHandle[] { }, Allocator.Temp));
    Up to you to use the additional c# array
     
  8. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    You don't seem to understand how the
    params
    keyword works. :)

    You can call this like so:
    Code (CSharp):
    1. JobHandle.CombineDependencies();
    2. JobHandle.CombineDependencies(foo);
    3. JobHandle.CombineDependencies(foo, bar);
    4. JobHandle.CombineDependencies(foo, bar, baz);
     
  9. yondercode

    yondercode

    Joined:
    Jun 11, 2018
    Posts:
    27
    Internally C# will allocate a managed array every time it is called which is extremely bad for performance.
     
    Nyanpas likes this.
  10. OUTTAHERE

    OUTTAHERE

    Joined:
    Sep 23, 2013
    Posts:
    656
    Yes, that was said. It's unfortunate but maybe the
    Span<T>
    proposal will come through in a year or two, and then to Unity in a decade or two.

    Honestly, I think if Unity is rewriting / transpiling so much IL code anyway, those syntactic fundamentals should be nearly trivial for them... (yes, looking at you,
    foreach
    inside Entities.ForEach)

    The primary reason to not use a DSL for DOTS is the ease of use and precision of C#, and inheriting the refactoring and inspection features of industry standard tools. Sadly, currently they're butchering this with assumptions and hidden bans / post-compile / runtime-errors-that-should-be-link-time-errors in the preview packages for DOTS.

    C# has an IL for that very reason, so you can apply your assumptions to the intermediate language or the machine language levels, rather than force the burden of knowledge (and inflexibility...) on the user.

    At the state it's currently in, DOTS-C# is vastly different from vanilla C#, and it is pretty glaring that the latter language can do more and more things that the former can't.
     
    Last edited: Jul 17, 2020
  11. yondercode

    yondercode

    Joined:
    Jun 11, 2018
    Posts:
    27
    Yeah,
    ForEach
    is completely magic (to me anyway) and
    CombineDependencies
    would be a perfect candidate for such use.

    Until there's a better way I'm just using a static utility method as a shortcut when combining more than 3 handles.
     
    Nyanpas and OUTTAHERE like this.
  12. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    939
    Sorry I miss read your post and was under the impresisons you were not aware of the nativearray option.
    That said, you can make your own extention method to the JobHandle that take in the job handle with the params keyword and internally allocate the native array of jobhandle to use in unity's combinedependency.

    Not tested :
    Code (CSharp):
    1. public static class JobHandleExtensions
    2. {
    3.     public static JobHandle CombineWithDependencies(this JobHandle jobHandle, params JobHandle[] otherDependancies)
    4.     {
    5.         NativeArray<JobHandle> handles = new NativeArray<JobHandle>(otherDependancies, Allocator.Temp);
    6.         jobHandle = JobHandle.CombineDependencies(jobHandle, JobHandle.CombineDependencies(handles));
    7.         handles.Dispose();
    8.         return jobHandle;
    9.     }
    10. }
    11.  
    12. public class DummySystem : SystemBase
    13. {
    14.     JobHandle[] otherDependencies;
    15.  
    16.     protected override void OnUpdate()
    17.     {
    18.         Dependency.CombineWithDependencies(otherDependencies);
    19.     }
    20. }
     
  13. thebanjomatic

    thebanjomatic

    Joined:
    Nov 13, 2016
    Posts:
    36
    That still allocates a managed array when calling the extension method and also is sub-optimal in terms of the number of calls to CombineDependencies.

    Short of changing the code-gen for params as a special case, the optimal and simplest approach I believe would instead be a fixed number of overloads with an explicit number of arguments like Joachim suggested in his previous comment.

    Something like this until it makes it into the main library:
    Code (CSharp):
    1. public static class JobHandleEx {
    2.     public static JobHandle CombineDependencies(JobHandle job0, JobHandle job1, JobHandle job2) {
    3.         var jobs = new NativeArray<JobHandle>(3, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
    4.         jobs[0] = job0; jobs[1] = job1; jobs[2] = job2;
    5.         var combined = JobHandle.CombineDependencies(jobs);
    6.         jobs.Dispose();
    7.         return combined;
    8.     }
    9.  
    10.     public static JobHandle CombineDependencies(JobHandle job0, JobHandle job1, JobHandle job2, JobHandle job3) {
    11.         var jobs = new NativeArray<JobHandle>(4, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
    12.         jobs[0] = job0; jobs[1] = job1; jobs[2] = job2; jobs[3] = job3;
    13.         var combined = JobHandle.CombineDependencies(jobs);
    14.         jobs.Dispose();
    15.         return combined;
    16.     }
    17. }
     
    Last edited: Jul 17, 2020
  14. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    I've been thinking a bit about this and I'd like to give my support to a particular course of action. I'm assuming here that IL transformation is an available tool, although I don't know what internal restrictions there may be on its use.

    Immediately
    • Add extra
      JobHandle.CombineDependencies
      overloads to support combining more at once
    • Also add extra overloads to
      JobHandle.CompleteAll
      for the same reason
    • Add PLUS operator support
    • Document clearly that
      JobHandle.CombineDependencies
      should be preferred over PLUS for performance reasons when there are more than two operands
    Sometime later
    • Add an IL transformation that turns operator chains like
      dep0 + dep1 + dep2
      into
      JobHandle.CombineDependencies(dep0, dep1, dep2)
    • Remove the documentation note saying to prefer
      JobHandle.CombineDependencies
    This is based on the assumption that the first set of actions are easy and quick, and that the IL transformation is possible, but significantly more work to get done and so less likely to happen if we ask for it as a first step. I'm hoping that this approach may allow this low priority feature to happen quickly, as the amount of work required for the immediately step is tiny.

    This would deal with the
    +=
    accumulation case immediately, as well as the common situation of combining only two dependencies like
    .Schedule(dep0 + dep1)
    . The rarer situation of combining three or more would simply remain unchanged for now. The only risk that I can see is that some people wouldn't properly read the documentation and would occasionally write
    dep0 + dep1 + dep2
    and incur a - presumably quite small - performance penalty until the sometime later IL transformation change is made.

    Optional extras
    • Rename
      CombineDependencies
      to
      Combine
      because the meaning is still clear and saving 12 characters may allow line wrapping to be avoided in a few extra cases - alternatively
      new JobHandle(dep0, dep1, dep2)
    • Allow
      CombineDependencies
      and
      CompleteAll
      to take a
      ReadOnlySpan<JobHandle>
      parameter as an alternative to
      NativeArray<JobHandle>
      so that arbitrary numbers of jobs can be combined using
      stackalloc
      without any
      Allocator
      use at all
    @Joachim_Ante does this sound like a practical way forward? I know this seems like a lot of work and discussion for a small API change that doesn't change runtime capabilities at all, but this thread has received a surprising amount of support - 18 likes and quite a few replies - for something that I assumed was only a pet issue of my own, so I'd like to continue to champion it as a meaningful quality of life improvement for the API.
     
    Last edited: Jul 18, 2020
  15. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    326
    I've been making assumptions about the relative time costs of the different methods of combining handles, so I thought I would actually try to benchmark it.

    These results have all of the usual caveats of microbenchmarks, and it's possible that these are unrepresentative as I'm combining the same handles on each iteration of the test - if there's some combination caching or CPU cache behaviour that affects this significantly then these results are useless. I did it this way because it seemed like a bad idea to schedule millions of jobs as part of the test.

    "us" means microseconds because the Mu character is a "banned word" on the forum.

    CombineDependencies(dep0, dep1, dep2)
    : 1.5 us
    CombineDependencies(dep0, CombineDependencies(dep1, dep2))
    : 1.6 us
    CombineDependencies
    with an array of length 100: 32 us, implying 0.32 us for each
    CombineDependencies(deps, nextDep)
    for 100 chained calls: 155 us, implying 1.6 us for each

    So as expected there is a performance cost to the "slow"
    JobHandle.CombineDependencies(dep0, JobHandle.CombineDependencies(dep1, dep2))
    form that the PLUS operator would give when using more than 2 operands without IL transformation, but it's not major. A user doing
    dep0 + dep1 + dep2
    instead of
    JobHandle.CombineDependencies(dep0, dep1, dep2)
    1,000 times a frame would only be losing about 100 us total. That's a fairly small cost considering that doing 1,000 inefficient dependency combinations per frame would be quite egregious!

    I'm doing this on an old i5 laptop and of course the costs might be slightly worse on mobile. I think these numbers indicate that the danger of somebody ignoring the documentation and using the operator with more than 2 operands without IL transformation is not significant enough to block this feature. Of course, if IL transformation happens there is no cost at all.


    Here's my benchmark code for recreation, scrutiny, and mean comments.

    Code (CSharp):
    1. using NUnit.Framework;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. using Unity.PerformanceTesting;
    5.  
    6. public class CombineDependenciesPerformanceTest
    7. {
    8.     const int Iterations = 100;
    9.  
    10.  
    11.     [Test, Performance]
    12.     public void ThreeAsArgs()
    13.     {
    14.         var job = new DummyJob();
    15.         var dep0 = job.Schedule();
    16.         var dep1 = job.Schedule();
    17.         var dep2 = job.Schedule();
    18.  
    19.         Measure
    20.             .Method(() => JobHandle.CombineDependencies(dep0, dep1, dep2))
    21.             .WarmupCount(100)
    22.             .MeasurementCount(100)
    23.             .IterationsPerMeasurement(Iterations)
    24.             .Run();
    25.  
    26.         JobHandle.CombineDependencies(dep0, dep1, dep2).Complete();
    27.     }
    28.  
    29.     [Test, Performance]
    30.     public void ThreeAsChain()
    31.     {
    32.         var job = new DummyJob();
    33.         var dep0 = job.Schedule();
    34.         var dep1 = job.Schedule();
    35.         var dep2 = job.Schedule();
    36.  
    37.         Measure
    38.             .Method(() => JobHandle.CombineDependencies(dep0, JobHandle.CombineDependencies(dep1, dep2)))
    39.             .WarmupCount(100)
    40.             .MeasurementCount(100)
    41.             .IterationsPerMeasurement(Iterations)
    42.             .Run();
    43.  
    44.         JobHandle.CombineDependencies(dep0, dep1, dep2).Complete();
    45.     }
    46.  
    47.     [Test, Performance]
    48.     public void OneHundredAsArrayExcludingCreation()
    49.     {
    50.         var job = new DummyJob();
    51.         var deps = new NativeArray<JobHandle>(100, Allocator.Temp);
    52.  
    53.         for (var i = 0; i < deps.Length; i++) deps[i] = job.Schedule();
    54.  
    55.         Measure
    56.             .Method(() => JobHandle.CombineDependencies(deps))
    57.             .WarmupCount(100)
    58.             .MeasurementCount(100)
    59.             .IterationsPerMeasurement(Iterations)
    60.             .Run();
    61.  
    62.         JobHandle.CombineDependencies(deps).Complete();
    63.     }
    64.  
    65.     [Test, Performance]
    66.     public void OneHundredAsArrayIncludingCreation()
    67.     {
    68.         var job = new DummyJob();
    69.         var deps = new NativeArray<JobHandle>(100, Allocator.Temp);
    70.  
    71.         for (var i = 0; i < deps.Length; i++) deps[i] = job.Schedule();
    72.  
    73.         Measure
    74.             .Method(() =>
    75.             {
    76.                 var deps2 = new NativeArray<JobHandle>(deps.Length, Allocator.Temp);
    77.                 for (var i = 0; i < deps2.Length; i++) deps2[i] = deps[i];
    78.                 JobHandle.CombineDependencies(deps2);
    79.                 deps2.Dispose();
    80.             })
    81.             .WarmupCount(100)
    82.             .MeasurementCount(100)
    83.             .IterationsPerMeasurement(Iterations)
    84.             .Run();
    85.  
    86.         JobHandle.CombineDependencies(deps).Complete();
    87.     }
    88.  
    89.     [Test, Performance]
    90.     public void OneHundredAsChain()
    91.     {
    92.         var job = new DummyJob();
    93.         var deps = new NativeArray<JobHandle>(100, Allocator.Temp);
    94.  
    95.         for (var i = 0; i < deps.Length; i++) deps[i] = job.Schedule();
    96.  
    97.         Measure
    98.             .Method(() => {
    99.                 var i = 0;
    100.                 var dep = default(JobHandle);
    101.  
    102.                 dep = JobHandle.CombineDependencies(dep, deps[0]);
    103.                 dep = JobHandle.CombineDependencies(dep, deps[1]);
    104.                 dep = JobHandle.CombineDependencies(dep, deps[2]);
    105.                 dep = JobHandle.CombineDependencies(dep, deps[3]);
    106.                 dep = JobHandle.CombineDependencies(dep, deps[4]);
    107.  
    108.                 dep = JobHandle.CombineDependencies(dep, deps[5]);
    109.                 dep = JobHandle.CombineDependencies(dep, deps[6]);
    110.                 dep = JobHandle.CombineDependencies(dep, deps[7]);
    111.                 dep = JobHandle.CombineDependencies(dep, deps[8]);
    112.                 dep = JobHandle.CombineDependencies(dep, deps[9]);
    113.  
    114.                 dep = JobHandle.CombineDependencies(dep, deps[10]);
    115.                 dep = JobHandle.CombineDependencies(dep, deps[11]);
    116.                 dep = JobHandle.CombineDependencies(dep, deps[12]);
    117.                 dep = JobHandle.CombineDependencies(dep, deps[13]);
    118.                 dep = JobHandle.CombineDependencies(dep, deps[14]);
    119.  
    120.                 dep = JobHandle.CombineDependencies(dep, deps[15]);
    121.                 dep = JobHandle.CombineDependencies(dep, deps[16]);
    122.                 dep = JobHandle.CombineDependencies(dep, deps[17]);
    123.                 dep = JobHandle.CombineDependencies(dep, deps[18]);
    124.                 dep = JobHandle.CombineDependencies(dep, deps[19]);
    125.  
    126.                 dep = JobHandle.CombineDependencies(dep, deps[20]);
    127.                 dep = JobHandle.CombineDependencies(dep, deps[21]);
    128.                 dep = JobHandle.CombineDependencies(dep, deps[22]);
    129.                 dep = JobHandle.CombineDependencies(dep, deps[23]);
    130.                 dep = JobHandle.CombineDependencies(dep, deps[24]);
    131.  
    132.  
    133.                 dep = JobHandle.CombineDependencies(dep, deps[25]);
    134.                 dep = JobHandle.CombineDependencies(dep, deps[26]);
    135.                 dep = JobHandle.CombineDependencies(dep, deps[27]);
    136.                 dep = JobHandle.CombineDependencies(dep, deps[28]);
    137.                 dep = JobHandle.CombineDependencies(dep, deps[29]);
    138.  
    139.                 dep = JobHandle.CombineDependencies(dep, deps[30]);
    140.                 dep = JobHandle.CombineDependencies(dep, deps[31]);
    141.                 dep = JobHandle.CombineDependencies(dep, deps[32]);
    142.                 dep = JobHandle.CombineDependencies(dep, deps[33]);
    143.                 dep = JobHandle.CombineDependencies(dep, deps[34]);
    144.  
    145.                 dep = JobHandle.CombineDependencies(dep, deps[35]);
    146.                 dep = JobHandle.CombineDependencies(dep, deps[36]);
    147.                 dep = JobHandle.CombineDependencies(dep, deps[37]);
    148.                 dep = JobHandle.CombineDependencies(dep, deps[38]);
    149.                 dep = JobHandle.CombineDependencies(dep, deps[39]);
    150.  
    151.                 dep = JobHandle.CombineDependencies(dep, deps[40]);
    152.                 dep = JobHandle.CombineDependencies(dep, deps[41]);
    153.                 dep = JobHandle.CombineDependencies(dep, deps[42]);
    154.                 dep = JobHandle.CombineDependencies(dep, deps[43]);
    155.                 dep = JobHandle.CombineDependencies(dep, deps[44]);
    156.  
    157.                 dep = JobHandle.CombineDependencies(dep, deps[45]);
    158.                 dep = JobHandle.CombineDependencies(dep, deps[46]);
    159.                 dep = JobHandle.CombineDependencies(dep, deps[47]);
    160.                 dep = JobHandle.CombineDependencies(dep, deps[48]);
    161.                 dep = JobHandle.CombineDependencies(dep, deps[49]);
    162.  
    163.  
    164.                 dep = JobHandle.CombineDependencies(dep, deps[50]);
    165.                 dep = JobHandle.CombineDependencies(dep, deps[51]);
    166.                 dep = JobHandle.CombineDependencies(dep, deps[52]);
    167.                 dep = JobHandle.CombineDependencies(dep, deps[53]);
    168.                 dep = JobHandle.CombineDependencies(dep, deps[54]);
    169.  
    170.                 dep = JobHandle.CombineDependencies(dep, deps[55]);
    171.                 dep = JobHandle.CombineDependencies(dep, deps[56]);
    172.                 dep = JobHandle.CombineDependencies(dep, deps[57]);
    173.                 dep = JobHandle.CombineDependencies(dep, deps[58]);
    174.                 dep = JobHandle.CombineDependencies(dep, deps[59]);
    175.  
    176.                 dep = JobHandle.CombineDependencies(dep, deps[60]);
    177.                 dep = JobHandle.CombineDependencies(dep, deps[61]);
    178.                 dep = JobHandle.CombineDependencies(dep, deps[62]);
    179.                 dep = JobHandle.CombineDependencies(dep, deps[63]);
    180.                 dep = JobHandle.CombineDependencies(dep, deps[64]);
    181.  
    182.                 dep = JobHandle.CombineDependencies(dep, deps[65]);
    183.                 dep = JobHandle.CombineDependencies(dep, deps[66]);
    184.                 dep = JobHandle.CombineDependencies(dep, deps[67]);
    185.                 dep = JobHandle.CombineDependencies(dep, deps[68]);
    186.                 dep = JobHandle.CombineDependencies(dep, deps[69]);
    187.  
    188.                 dep = JobHandle.CombineDependencies(dep, deps[70]);
    189.                 dep = JobHandle.CombineDependencies(dep, deps[71]);
    190.                 dep = JobHandle.CombineDependencies(dep, deps[72]);
    191.                 dep = JobHandle.CombineDependencies(dep, deps[73]);
    192.                 dep = JobHandle.CombineDependencies(dep, deps[74]);
    193.  
    194.  
    195.                 dep = JobHandle.CombineDependencies(dep, deps[75]);
    196.                 dep = JobHandle.CombineDependencies(dep, deps[76]);
    197.                 dep = JobHandle.CombineDependencies(dep, deps[77]);
    198.                 dep = JobHandle.CombineDependencies(dep, deps[78]);
    199.                 dep = JobHandle.CombineDependencies(dep, deps[79]);
    200.  
    201.                 dep = JobHandle.CombineDependencies(dep, deps[80]);
    202.                 dep = JobHandle.CombineDependencies(dep, deps[81]);
    203.                 dep = JobHandle.CombineDependencies(dep, deps[82]);
    204.                 dep = JobHandle.CombineDependencies(dep, deps[83]);
    205.                 dep = JobHandle.CombineDependencies(dep, deps[84]);
    206.  
    207.                 dep = JobHandle.CombineDependencies(dep, deps[85]);
    208.                 dep = JobHandle.CombineDependencies(dep, deps[86]);
    209.                 dep = JobHandle.CombineDependencies(dep, deps[87]);
    210.                 dep = JobHandle.CombineDependencies(dep, deps[88]);
    211.                 dep = JobHandle.CombineDependencies(dep, deps[89]);
    212.  
    213.                 dep = JobHandle.CombineDependencies(dep, deps[90]);
    214.                 dep = JobHandle.CombineDependencies(dep, deps[91]);
    215.                 dep = JobHandle.CombineDependencies(dep, deps[92]);
    216.                 dep = JobHandle.CombineDependencies(dep, deps[93]);
    217.                 dep = JobHandle.CombineDependencies(dep, deps[94]);
    218.  
    219.                 dep = JobHandle.CombineDependencies(dep, deps[95]);
    220.                 dep = JobHandle.CombineDependencies(dep, deps[96]);
    221.                 dep = JobHandle.CombineDependencies(dep, deps[97]);
    222.                 dep = JobHandle.CombineDependencies(dep, deps[98]);
    223.                 dep = JobHandle.CombineDependencies(dep, deps[99]);
    224.             })
    225.             .WarmupCount(100)
    226.             .MeasurementCount(100)
    227.             .IterationsPerMeasurement(Iterations)
    228.             .Run();
    229.  
    230.         JobHandle.CombineDependencies(deps).Complete();
    231.     }
    232.  
    233.  
    234.     struct DummyJob : IJob
    235.     {
    236.         public void Execute() { }
    237.     }
    238. }
    239.  
     
    Last edited: Jul 19, 2020
    jasonboukheir and yondercode like this.
  16. RamType0

    RamType0

    Joined:
    Sep 11, 2018
    Posts:
    67
    Why is this not done yet ?
    This seems to be very easy to implement.