Search Unity

[Solved] Data copying issues between jobs when building kdTree within IJob

Discussion in 'Entity Component System' started by chanfort, May 26, 2019.

  1. chanfort

    chanfort

    Joined:
    Dec 15, 2013
    Posts:
    641
    I was recently working with kdTree based collisional local avoidance, which is possible alternative for hash based collisional avoidance, introduced in Austin Presentation demo. The algorithm seems to be working well but I run into one of the performance issues that I need to call jobHandle.Complete() as otherwise data is not properly calculated and passed to the job. I put the repo on GitHub with kdTree collisional avoidance file (KDTreeSystem.cs) here.

    When running kdTreeTests scene, it can be switched between correct calculations when jobHandle.Complete() is called and wrong calculations when the job is scheduled and its handle passed to the next job instead. The mode is set with buildKDInJob (default one is set to run wrong calculations). It can be switched by pressing A key while in play mode.

    The problem comes in this part of code:
    Code (CSharp):
    1. JobHandle kdBuildHandle = copyJobsHandle;
    2.         if(buildKDInJob)
    3.         {
    4.             // runs wrong
    5.             KDBuild kdBuild = new KDBuild
    6.             {
    7.                 kdTree = kd,
    8.                 postions = translations
    9.             };
    10.             kdBuildHandle =  kdBuild.Schedule(copyJobsHandle);
    11.         }
    12.         else
    13.         {
    14.             // runs correctly
    15.             copyJobsHandle.Complete();
    16.             KDBuild kdBuild = new KDBuild
    17.             {
    18.                 kdTree = kd,
    19.                 postions = translations
    20.             };
    21.             kdBuild.Execute();
    22.             kd = kdBuild.kdTree;
    23.         }
    24.        
    25.         KDCollisions kDCollisionsJob = new KDCollisions
    26.         {
    27.             kdTree = kd,
    28.             positions = translations,
    29.             velocities = velocities,
    30.             dt = Time.deltaTime,
    31.         };
    32.         JobHandle kDCollisionsJobHandle = kDCollisionsJob.Schedule(m_Group, kdBuildHandle);
    So it seems like KDBuild job is not properly running when scheduled, or data is not being passed to kdCollisionsJob, or kd is not being updated.

    The weird part is that it starts to calculate after several seconds from the start when collisions appears to work properly and units avoids each other. It doesn't look like it would be calculating correctly in all updates as some units are still not avoiding each other. While running the mode with jobHandle.Complete() it is always working very well. There are also no errors when running in the incorrect mode.

    So I was wondering what could potentially be causing this issue?
     
  2. chanfort

    chanfort

    Joined:
    Dec 15, 2013
    Posts:
    641
    Just fixed the issue. It turned out that I was making a mistake when writing to int in one job, which was not saved for the next job. Found this issue discussed before:
    https://forum.unity.com/threads/job-system-output-scalar-value-from-job.512194/

    I guess the takeaway from this is to keep printing until you find it :) .

    Anyways, I pushed the update to the repo. Results looks very exciting, 40k local avoidance agents with kdtree rebuild and 1st nearest neighbour searches running in Unity Editor at 30 FPS. In comparison the previous version which was calling jobHandle.Complete() was running only 8k agents at this framerate.
     
    Xerioz likes this.