Search Unity

Question Job System - can you read rigidbody velocity from Job threads?

Discussion in 'C# Job System' started by funkyCoty, Aug 23, 2020.

  1. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    I just need to read Rigidbody.velocity, not write.
     
  2. Ryunis

    Ryunis

    Joined:
    Dec 23, 2014
    Posts:
    24
    I'm assuming you're talking about the regular gameobject Rigidbody component, in which case no, you cannot interact with managed code on the main thread inside jobs. You can disable burst compilation and run it on the main thread, but you won't see any performance benefits in that case. Another solution would be to copy all of the necessary Rigidbody velocities into a Native Container (like NativeArray) and pass that to your job.
     
    bb8_1 likes this.
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    I understand why we cannot write to Rigidbodies directly from the Job system, but why can we not read from them?

    My bottleneck currently is reading Rigbody.velocity on the main thread, into a NativeArray. Something that should be safe to do, just read from rigibody and write to nativearray.

    It costs about 0.5ms to just read about 1000 rigidbody's velocities on the main thread, in a loop. It's very simple code, just for( ... ) { array[index] = body_array[index].velocity } basically
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    How can you know its safe to do? What if your job is executing at the same time the main physics is updating and writing to the rigidbody?
     
  5. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    I assume he only needs [ReadOnly]
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Yes but physx doesn't care about your readonly attribute.

    But the simple fact is, very few unity objects can be used off main thread.
     
    Nyanpas likes this.
  7. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,269
    I'd ask this in the Experimental Physics forums. The developers capable of adding this API are active there.
     
  8. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Because physics are not always running. You can off-thread get raycasts, this is proof enough.
     
  9. james7132

    james7132

    Joined:
    Mar 6, 2015
    Posts:
    166
    There have always been oddities with the Unity API and thread safety checks. Jobs do not have mutexs and sempahores for synchronization control, and there is no accessible synchronization control for built in engine systems. As @tertle has suggested: what may be safe from another thread at a given time may not be safe all the time. Without synchronization control, you risk reading while the value is being written to in the physics phase of the game loop. As a general rule of thumb, to avoid these hazards Jobs do not allow access into these managed components at any time. The sole exception may be TransformAccess, and that is only allowed due to synchronization controls around IJobParallelForTransform being built into the engine.
     
  10. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    This is just plain wrong. Physics is NOT always running, you can see this in the profiler. It runs at a fixed rate, always before the Update() loop starts for your scripts. It should be safe to query / read during the Update loop, as long as any jobs accessing rigidbody data is .Complete()'d before the next FixedUpdate.
     
  11. james7132

    james7132

    Joined:
    Mar 6, 2015
    Posts:
    166
    Perhaps I'm not being clear enough in the wording. I'm well aware of what is done in the player loop on the main thread. The main issue is that Jobs are not bound by the loop on the main thread without synchronization points (i.e. calling JobHandle.Complete).

    OK great. However, Unity cannot tell from static analysis whether your job is stopped within the same Update loop or passed or stored for later use. If left uncompleted and it runs longer than the actual Update section of the player loop, there's a high chance for a race condition. The only two generic solutions for this are:
    1. Block all access to managed memory from jobs.
    2. Create a special job type (like IJobParallelForTransform) with special main-thread checks to either autokill the job or introduce a synchronization point before each physics update.
    While the latter is doable, the former is easier to implement, already in place and solves more than just access to Rigidbody variables.

    What is required that you read the current state of a Rigidbody such that you can't pass it in as a ReadOnly variable to the job?
     
  12. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Okay, and? Either let us handle it, or force jobs that need to access Rigidbody data to automatically .Complete() at the start of a physics frame.

    What's the problem with this? Has Unity discussed why this isn't an option?

    As I've already mentioned, my current bottleneck is simply reading the velocities from a list of Rigidbodies.
     
  13. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,269
    I doubt there is a technical limitation other than developer time. That's why I suggest you bring this to the experimental physics forums. The people who could actually implement such a feature for you hang out there.
     
  14. Harry-Aiden

    Harry-Aiden

    Joined:
    May 5, 2020
    Posts:
    2
    Actually, I think we need like rigidbody acess struct for developer to control component use in job, in our project there are lots of simulation using job to caculate based on rigidbody data. I can promise when we start rigidbody job there will be nothing change in main thread about rigidbody property,because we will wait for it.For other user component, it has the same situation.