Search Unity

Overhead of New'ing a Job? Should I keep the reference?

Discussion in 'Entity Component System' started by quitebuttery, Jun 4, 2020.

  1. quitebuttery

    quitebuttery

    Joined:
    Mar 12, 2011
    Posts:
    329
    There seems to be significant overhead in New'ing a job. Since my objects schedule these same jobs over and over--should I just cache the reference to the job and then fill the members of the struct with current data and reschedule it instead of new'ing it every time I want to schedule?
     
    DragonCoder likes this.
  2. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Since jobs are just structs (which implement a job interface), I’m not sure why creating them would be expensive.

    it may be More likely that the calls used to populate a job’s values are what you’re measuring. Calls like GetBufferFromEntity(), or CreateEntityCommandBuffer() for example.

    In that case, some of those calls would be necessary to make before each time the job is scheduled. ECBs, for example, are invalid once they’ve been played back. That could invalidate the savings you would get from caching and trying to reuse the job struct.
     
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    A ToComponentDataArray or ToEntityArray could be expensive culprits. Care to show code and profiling methods?
     
  4. quitebuttery

    quitebuttery

    Joined:
    Mar 12, 2011
    Posts:
    329
    I think what my problem is--I've got, say, 100 boids. I'm trying to make the boid AI update method a job instead of using 100 different update() methods.

    So in Update, I schedule the job with the boid AI in it. And then in lateupdate I see if it's complete, and then call complete() on the job, pull the data I need out of it, and update the GameObject's position.

    I don't see much of a performance increase vs just having this AI code in the update() method. There seems to be some, but not much.

    I think what I need to do is get rid of update altogether, and make a manager that takes every single boid, and schedules a parallel job for each one. They'll deposit the results in some pre-allocated native arrays and then in lateupdate I'll see which jobs are done and update their game objects?

    Coding jobs is super fun BTW--it's half art, half science. :)
     
  5. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    By "boid", do you mean a single object moving around or a separate flock?

    A common pattern in MonoBehaviour context is to schedule jobs in Update which perform the heavy calculations and write the results into NativeArrays, and then in LateUpdate, schedule and immediately Complete an IJobParallelForTransform job which writes the results to the Transforms.
     
    MNNoxMortem likes this.
  6. quitebuttery

    quitebuttery

    Joined:
    Mar 12, 2011
    Posts:
    329
    This is for each individual boid int he flock. So I think my big problem here is I have to do a circle cast and a raycast for the boid visibility check, before I schedule the job. The game is 2D, so there is no equivalent of RaycastCommand in Physics2D to do a raycast in a job. There might not be any way to solve my bottleneck until this is implemented. All Physics2D casts need to be done in the main thread.