Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Garbage from subscribing to collision events
#1
Can we have a conversation about the ridiculous amount of garbage that is generated from subscribing to collision events. I've seen anywhere from 25-30kb to 200-300kb on almost every frame just by subscribing to collision events. I've tried e-mailing support but no solution was ever provided. Is there nothing you fine programmers at Obi can do to fix this? There is no way you can have this much garbage generating over and over without crashing performance. This is a ridiculous price (and practically unusable one) to pay for getting some information from collisions. I implore you to please take a look.
Reply
#2
(16-12-2017, 11:16 PM)writer51 Wrote: Can we have a conversation about the ridiculous amount of garbage that is generated from subscribing to collision events. I've seen anywhere from 25-30kb to 200-300kb on almost every frame just by subscribing to collision events. I've tried e-mailing support but no solution was ever provided. Is there nothing you fine programmers at Obi can do to fix this? There is no way you can have this much garbage generating over and over without crashing performance. This is a ridiculous price (and practically unusable one) to pay for getting some information from collisions. I implore you to please take a look.

Hi!

I'm well aware of this and it is one of the areas that has been improved for 3.3. From now on, zero garbage will be generated per frame when subscribing to the OnCollision event, or the OnFluidUpdated event.

Tomorrow will try to get you a patch so that you can benefit from this improvement right now.

cheers!
Reply
#3
(17-12-2017, 12:29 AM)josemendez Wrote: Hi!

I'm well aware of this and it is one of the areas that has been improved for 3.3. From now on, zero garbage will be generated per frame when subscribing to the OnCollision event, or the OnFluidUpdated event.

Tomorrow will try to get you a patch so that you can benefit from this improvement right now.

cheers!

Can I get a Hallelujah! THANK YOU
Reply
#4
(17-12-2017, 02:00 AM)writer51 Wrote: Can I get a Hallelujah! THANK YOU

This has been a long sought-after thing for us too! Sonrisa

Ok, so here's the patch and installation instructions. It will be a little hard to apply, as you must manually modify the existing ObiSolver.cs file in a couple places.

1.- Replace the existing ObiCollisionEventArgs and ObiFluidEventArgs class implementations (found at the beginning of ObiSolver.cs) with this:
Code:
public class ObiCollisionEventArgs : EventArgs{
        public ObiList<Oni.Contact> contacts = new ObiList<Oni.Contact>();    /**< collision contacts.*/
    }

    public class ObiFluidEventArgs : EventArgs{

        public ObiList<int> indices = new ObiList<int>();            /**< fluid particle indices.*/
        public ObiList<Vector4> vorticities = new ObiList<Vector4>();
        public ObiList<float> densities = new ObiList<float>();

    }

       private ObiCollisionEventArgs collisionArgs = new ObiCollisionEventArgs();
    private ObiFluidEventArgs fluidArgs = new ObiFluidEventArgs();

2.- Replace TriggerFluidUpdateEvents and TriggerCollisionEvents functions with these:
Code:
private void TriggerFluidUpdateEvents(){

        int numFluidParticles = Oni.GetConstraintCount(oniSolver,(int)Oni.ConstraintType.Density);
        
        if (numFluidParticles > 0 && OnFluidUpdated != null){

            fluidArgs.indices.SetCount(numFluidParticles);
            fluidArgs.vorticities.SetCount(maxParticles);
            fluidArgs.densities.SetCount(maxParticles);

            Oni.GetActiveConstraintIndices(oniSolver,fluidArgs.indices.Data,numFluidParticles,(int)Oni.ConstraintType.Density);
            Oni.GetParticleVorticities(oniSolver,fluidArgs.vorticities.Data,maxParticles,0);
            Oni.GetParticleDensities(oniSolver,fluidArgs.densities.Data,maxParticles,0);

            OnFluidUpdated(this,fluidArgs);
        }
    }

    private void TriggerCollisionEvents(){
    
        int numCollisions = Oni.GetConstraintCount(oniSolver,(int)Oni.ConstraintType.Collision);

        if (OnCollision != null){

            if (numCollisions > 0)
            {
                collisionArgs.contacts.SetCount(numCollisions);
                Oni.GetCollisionContacts(oniSolver,collisionArgs.contacts.Data,numCollisions);
            }
    
            OnCollision(this,collisionArgs);

        }
    }

Lastly, include the ObiList.cs file you'll find attached in your project. That should be it! Collision and fluid update events will only generate a small amount of garbage in certain frames, when the amount of contacts/particles grows past the arrays capacity. Most frames, zero garbage will be generated.


Let me know if you have any issues with this.


Attached Files
.cs   ObiList.cs (Size: 3.11 KB / Downloads: 4)
Reply
#5
Thanks Jose, upgrade process went great. Everything seems fine, no garbage which is a plus!
Sadly, I am actually getting slower performance. I suspect because it's taking longer to iterate through the list than the array, I'm going to try and mess around to see if I can iterate through the results faster to make it worth it.

I'll report back anything I find....regardless, thank you for implementing this, it helps give me an idea of how to expand obi in other ways as well as eliminating the crazy garbage that existed previously. Great work!
Reply
#6
I just wanted to confirm because I did new benchmarks in a clean project. The new update is massively slower, despite the fact that it removes the garbage collection problem. Thank you for trying to fix this, but my recommendation is not to push this as an update for 3.3. I'm getting about 1/2-1/3 framerate of the old version. Garbage is preferable to that. If you guys have any other ideas please share them, otherwise I guess I will do my best with the regular version for now. 

Tested using collision event handler script included with the package (the commented out part with the color change).
Reply
#7
(17-12-2017, 07:37 PM)writer51 Wrote: I just wanted to confirm because I did new benchmarks in a clean project. The new update is massively slower, despite the fact that it removes the garbage collection problem. Thank you for trying to fix this, but my recommendation is not to push this as an update for 3.3. I'm getting about 1/2-1/3 framerate of the old version. Garbage is preferable to that. If you guys have any other ideas please share them, otherwise I guess I will do my best with the regular version for now. 

Tested using collision event handler script included with the package (the commented out part with the color change).

Hi there,

In all our tests, this change makes things run between 5-10% faster than before, to the point that there's no noticeable difference between being subscribed to the collision events or not.
Also there's no reason for it to be slower, as the implementation is basically the same but reusing the same array and resizing it incrementally instead of recreating it from scratch every frame. It still uses an array under the hood (just like List<> does), and iterates over it in the exact same way (not using enumerators or anything, just the [] operator).

Make sure that you're not running with deep profiling enabled, as that does reduce performance by at least 30% in all cases. In some complex scenes, we've seen reductions of up to 80%. This applies to all Unity games. See:
https://docs.unity3d.com/560/Documentati...indow.html

Quote:Note that Deep Profiling incurs a very large overhead and uses a lot of memory, and as a result your game will run significantly slower while profiling.
Reply
#8
Hrm, I don't understand the discrepancy between your tests and mine, unless I am missing something.
I started in a fresh project and bench marked it before any changes using the sample collision script provided (just the commented out part that does the material color change). With no profiler enabled at all I was hitting 125-140 fps with 7-8 ms. Adding the changes I dropped down to 60-80 fps or so. Would it be possible to send me a test project (zip or whatever) so I can benchmark the new code in it, then change it back and benchmark it after?

I'd love to help and test in anyway I can because my current game requires heavy dependence on Obi Fluid so anything I can do to help improve it would be my pleasure. This is Tigrero btw, been working with Obi for a while Sonrisa

Edit: On the sample collision script I meant I commented in the material color change part and commented out the top part. Changed Collider collider, to Component collider.

Edit: I can also screenshare or make a vid if you want
Reply
#9
(17-12-2017, 08:37 PM)writer51 Wrote: Hrm, I don't understand the discrepancy between your tests and mine, unless I am missing something.
I started in a fresh project and bench marked it before any changes using the sample collision script provided (just the commented out part that does the material color change). With no profiler enabled at all I was hitting 125-140 fps with 7-8 ms. Adding the changes I dropped down to 60-80 fps or so. Would it be possible to send me a test project (zip or whatever) so I can benchmark the new code in it, then change it back and benchmark it after?

I'd love to help and test in anyway I can because my current game requires heavy dependence on Obi Fluid so anything I can do to help improve it would be my pleasure. This is Tigrero btw, been working with Obi for a while Sonrisa
Hi Tigrero! didn't recognize you Sonrisa

We test all sample scenes in an empty project before and after making a performance critical change. I just tested the FluidFoam scene, with the old method I get 75-80 fps, with the new one I get 84-90. Tomorrow I will take a deeper look at it, and maybe send you a test scene with an easy switch to toggle between the two methods, but I see no reason why the new method would be slower.


Edit: Off the top of my head: in the CollisionEventHandler, make sure you iterate to contacts.Count, not contacts.Data.Length. contacts.Data.Length refers to the internal backing array size (similar to List<>'s Capacity), which can be much larger than the actual amount of contacts. That would leave the event handler iterating over an enormous, mostly empty, array. Can this be the cause?

cheers,
Reply
#10
No problem, I love working with Obi what can I say!

I did change it to count yeah, I am doing another retest just in case I missed something. Would you be open to a skype screenshare or video if I e-mail it to you just so you can see what I am doing, maybe there's something wrong...Should be done with the retest in a few minutes then I can redo it all step by step either via screenshare or by vid just to show you the steps. It takes only about 2-3 minutes total.
Reply