Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Concerns about performance
#1
Hi!

I've successfully used Obi Rope in my project, and I am very satisfied with how it works. However, I'm still a little concerned about the performance, and I hope that it can be somehow improved.

For context, my project has an ObiFixedUpdater with 3 substeps and 3 attached solvers. Each solver has 8 ObiRods, they're 0.6m long with resolution of 0.2 and have two static and two dynamic attachments. All the collisions are disabled, the only constrains enabled in solvers are pin, stretch&shear and bend&twist with sequential evaluation and 1 iteration. The rods use ObiRopeExtrudedRenderer with ObiPathSmoother with smoothing set to 1.

   
   

What worries me are the long durations of BeginStep in FixedUpdate and Interpolate in Update. Also, I'm wondering if it should work that way, that the Substep worker threads are barely used in parallel, and are idle most of the time. The most interesting part is that in build the durations of this processes under same conditions can get even 2 times longer. I've tried to do all the steps listed in the manual, i.e. enabling Burst compilation and disabling jobs debugger, safety checks and leak detection, but I didn't notice any big change in performance. I'm using 1.8.4 version of Burst package, 1.2.6 version of Mathematics and 2.1.4 version of Collections, on Unity 2022.3.0f1.

Is there a way to employ all the worker threads more, so the calculations in the steps can be done more efficiently, or maybe I've missed some steps in the setup and that causes this issues? I managed to cut some of the calculations, so the simulation runs a little bit faster, but I hope that there is still some room for improvement. I would be really grateful for your help.
Reply
#2
(27-08-2023, 10:46 PM)1234567398 Wrote: Hi!

I've successfully used Obi Rope in my project, and I am very satisfied with how it works. However, I'm still a little concerned about the performance, and I hope that it can be somehow improved.

For context, my project has an ObiFixedUpdater with 3 substeps and 3 attached solvers. Each solver has 8 ObiRods, they're 0.6m long with resolution of 0.2 and have two static and two dynamic attachments. All the collisions are disabled, the only constrains enabled in solvers are pin, stretch&shear and bend&twist with sequential evaluation and 1 iteration. The rods use ObiRopeExtrudedRenderer with ObiPathSmoother with smoothing set to 1.

What worries me are the long durations of BeginStep in FixedUpdate and Interpolate in Update.

Hi!

BeginStep() performs basic solver bookkeeping such as keeping collider data up to date and Interpolate() performs rope mesh generation by extruding a section along the rope's path. Neither process can be parallelized since:

A) Most bookkeeping must be done on the main thread, due to Unity's API calls that can't be called from any other thread.

B) ObiRopeExtrudedRenderer uses parallel transport to propagate a frame along the rope's path. Despite its name, this is an inherently sequential algorithm, since each step's input is the output of the previous step. In your case, you might benefit from using either a simpler ObiRopeSection asset (with fewer segments) or a ObiRopeLineRenderer to cut on the amount of geometry dealt with during mesh generation. See the "RopeNet" sample scene for an example of using ObiRopeLineRenderer together with a normal map to draw many ropes efficiently.


(27-08-2023, 10:46 PM)1234567398 Wrote: Also, I'm wondering if it should work that way, that the Substep worker threads are barely used in parallel, and are idle most of the time. The most interesting part is that in build the durations of this processes under same conditions can get even 2 times longer.

Substeps perform the actual physics simulation. In your case though, since there's no collision detection, ropes are very low resolution and there's only 1 constraint iteration, there's barely any work to do for the worker threads and most of the time is spent scheduling jobs.

(27-08-2023, 10:46 PM)1234567398 Wrote: Is there a way to employ all the worker threads more, so the calculations in the steps can be done more efficiently

No, to employ worker threads you need tasks that can be done in parallel. Except for bend/twist and stretch/shear constraints (of which there's few since your ropes are low-resolution), there's no parallel work to do in your case.

Your main bottleneck right now is mesh generation in Interpolate(). You can speed this up by using a simpler rendering method, as suggested above.

kind regards,
Reply
#3
As a side note: keep in mind that profiling has an impact on performance.

This is specially true when using development builds w/ deep profiling support, since no optimizations are performed on the code and extra code is inserted for measuring performance.

kind regards,
Reply
#4
Hi,

We're seeing similar issues as the original poster reports, with BeginStep taking as much as 15ms each frame.

Your answers doesn't really provide a solution for fixing this, so my question is: "is there a way to solve this?". 

I've seen reviews stating how well optimized ObiRope is supposed to be but this plugin is dragging our game's performance down the drain.
Reply
#5
(17-10-2023, 02:49 PM)hanlid Wrote: Hi,

We're seeing similar issues as the original poster reports, with BeginStep taking as much as 15ms each frame.

Your answers doesn't really provide a solution for fixing this, so my question is: "is there a way to solve this?". 

I've seen reviews stating how well optimized ObiRope is supposed to be but this plugin is dragging our game's performance down the drain.

Hi,

OP’s issue was mesh generation, which takes place in Interpolate() at the very end of the frame. In his case, the suggested solution was to switch to a simpler rendering method.

I assume you’re using Burst, correct?

Could you share a screenshot of your profiler in timeline mode, with BeginStep clearly visible in it? It should not take more than half a millisecond under normal circumstances, couple milliseconds tops if you have thousands of colliders in the scene. 15 ms means either Burst is not properly compiling the code and falling back to regular C#instead, or some other issue.

Having some more information about your scene setup (how many solvers/updaters in it, solver settings, etc) would be useful too, as it would help me determine what the exact cause might be.

Some general performance tips that could be helpful (most are very basic though):
http://obi.virtualmethodstudio.com/manua...etips.html

Kind regards,
Reply
#6
(17-10-2023, 03:50 PM)josemendez Wrote: Hi,

OP’s issue was mesh generation, which takes place in Interpolate() at the very end of the frame. In his case, the suggested solution was to switch to a simpler rendering method.

I assume you’re using Burst, correct?

Could you share a screenshot of your profiler in timeline mode, with BeginStep clearly visible in it? It should not take more than half a millisecond under normal circumstances, couple milliseconds tops if you have thousands of colliders in the scene. 15 ms means either Burst is not properly compiling the code and falling back to regular C#instead, or some other issue.

Having some more information about your scene setup (how many solvers/updaters in it, solver settings, etc) would be useful too, as it would help me determine what the exact cause might be.

Some general performance tips that could be helpful (most are very basic though):
http://obi.virtualmethodstudio.com/manua...etips.html

Kind regards,

Thanks for your quick reply Jose. In our case it was definitely that we hadn't enabled Burst. Now we're down to around 1 ms for BeginStep.

(You probably already know this but there's a typo in NativeMultilevelGrid line 74, length should be Length.)

Cheers
Reply
#7
(18-10-2023, 07:58 AM)hanlid Wrote: Thanks for your quick reply Jose. In our case it was definitely that we hadn't enabled Burst. Now we're down to around 1 ms for BeginStep.

Galo you found the cause Sonrisa

(18-10-2023, 07:58 AM)hanlid Wrote: (You probably already know this but there's a typo in NativeMultilevelGrid line 74, length should be Length.)

Thanks! Yes, I'm aware of this.

It's not a typo, in older versions of the Collections package it was called length. In newer versions they've changed it to a capital L, so in upcoming Obi versions we'll bump the minimum required version of Collections and use Length accordingly.

kind regards,
Reply