#Syncing Transform with LocalToWorld

1 messages · Page 1 of 1 (latest)

errant rapids
#

I have to sync my Skinned Animations GO (GPUI Crowd Animations) with their respective Entity, but I have noticed that setting the transform position is pretty expensive.

~1.5ms for 2k Transforms, which is enormously high

I am currently syncing the positions in LateUpdate(), but tried using IJobParallelForTransform as well, which resulted in ~ the same time, but I could do it in a Job. Unfortunately this only allows for .Schedule() and not .ScheduleParallel().

Is there any way to speed the syncing up?

sullen spire
#

Howdy - how many individual hierarchies do you have? Can you show the code with which you're syncing?

errant rapids
# sullen spire Howdy - how many individual hierarchies do you have? Can you show the code with...

Hey there, it seems like I have been using IJobParallelForTransform wrongly, as I have been making a new TransformAccessArray(_animationPositions); every LateUpdate() tick
This was the bottleneck on the IJobParallelForTransform side, now the syncing takes ~0.22ms for 2000 Transforms + some other code which happens before

And to my astonishment, IJobParallelForTransform actually automatically uses a parallel for. I was probably just confused, since normally calling .Schedule() in Jobs results in creating 1 Job and not x Jobs

Would it be by any chance possible to change the .Schedule() call with a .ScheduleParallel()? This makes the function call more logical (at least for me)

If you would like some additional information, I am glad to provide it

sullen spire
#

Thanks! It's kind of an odd duck since it goes parallel by hierarchy, so it's potentially entirely serial if you have one long string of transforms.

I'd love to see the code, 0.22ms isn't trivial. Also the # of hierarchies you're processing if you have that handy

errant rapids
#

Oh I see 👍

-edit-
I did some testing and came to a new conclusion.

  1. I can actually use [BurstCompile] with the IJobParallelForTransform, I didn't even think about the possibility, since Transform is not a blittable type (just tried it out of curiosity)
  2. Starting and waiting for the Job to finish takes by far the most amount of time
  • ~0.25 ms starting the Job + waiting for it to finish with 2k Characters, 1 Character = 4 Transforms (see messages below)
  • ~0.50 ms starting the Job + waiting for it to finish with 4k Characters
  1. Using Burst doesn't change the ms on the Main Thread with 2k Characters, but with 4k it does
  • 2k Characters, no Burst = ~0.25 ms, Workers take ~ 0.10-0.15 ms; with Burst = ~0.25 ms , Workers take ~ 0.05, only 1 Worker takes 0.10
  • 4k Characters, no Burst = ~0.50-0.60 ms, Workers take ~ 0.20-0.35 ms; with Burst = ~0.50 ms, Worker take ~0.10-0.20 ms

I am not quite sure how it is possible that Burst increases the speed up of the Workers, but the Main Thread still has to wait the same amount of time as if Burst was not active. And the speed up of Burst isn't as big as I expected.
-edit end-

Entities 1.0.0-pre.65 (I haven't updated to 1.0.8 yet)
Unity 2022.2.16

Quick rundown about the code:

class CrowdManagerAB

  • Gets the NativeArray<float3> and NativeArray<quaternion> from the ECS World every LateUpdate tick
  • Syncs the Position and Rotation of the Transforms in LateUpdate() using IJobParallelForTransform
#

That's what the Hierarchy looks like
It's 4 Transforms in total

Root

  • Deactivated Skinned Model (by the Asset)
  • Right hand bone
    • Model of a Sword
#

Tested with 2k Characters = 8k Transforms
~0.25 ms for the LateUpdate() with 5 Workers in this specific time frame

0.12 ms for Worker 0
0.15 ms for Worker 1
0.14 ms for Worker 2
0.10 ms for Worker 3
0.10 ms for Worker 4

#

The helper function used in UpdateCharacterTransformData()
Line: 95 and 96

errant rapids
#

Just to show that there are in fact 2000 Characters aka 8000 Transforms

#

Also 2000 Characters in Entity World

#

If you need anything else, feel free to ask!

#

Quick screenshot to show that the Bursted Workers indeed take ~0.05 ms with 2k Characters and the Main Thread still take ~0.25 ms

errant rapids
sullen spire
#

Tough to say! I expect 2k characters of 4 bones each to be a pretty good test case. The job kickoff numbers seem a little high, I presume there's some data copying going on. If you don't have a minimal test project I can profile then I can put one together at some point

errant rapids
# sullen spire Tough to say! I expect 2k characters of 4 bones each to be a pretty good test c...

That would be greatly appreciated, if you could check the project out! I have put everything together into a new project, which basically behaves the same way as my main project

Info regarding the Project:
Unity 2022.2.16 and Entities 1.0.8

There are 3 Scripts

  • CharactersSyncDataSystemTEST (The System which updates the NativeArrays)
  • TransformSyncTEST (The Mono class which Syncs the Transforms using the NativeArrays inside a Job)
  • UtilsAB (My Utils class, need for getting the Component from ECS)

There is 1 Prefab "Character" with 4 children and 1 Scene

If you want to change the number of instantiated Prefabs just change the "CHARACTER_COUNT" in "CharactersSyncDataSystemTEST"

And I have run the Profiler really quickly and the ms are ~ the same as in my post, but now they weren't even consistent, but were jumping from 0.2-0.6 very weird

I believe that the Assets, Packages and ProjectSettings should be enough to open the project, but please let me know if there is anything else you would need.

#

I think you are right with the copying. I have just started the Job and left the Execute() empty and the Main Thread took 0.2-0.6 ms and the Workers 0ms

#

I believe it has something to do with the Transform[] of the TransformSyncingJob, since when I start the Job with NativeArrays with a length of 0, it takes the same amount of time

var job = new TransformSyncingJob {positions = new NativeArray<float3>(0, Allocator.TempJob), rotations = new NativeArray<quaternion>(0, Allocator.TempJob)};
sullen spire
#

Sweet, I can't take a look right at the moment but I'll add it to my list to check out