Minimizing/eliminating allocations during Update?

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
sqrtpi
Posts: 9
Joined: Tue Nov 22, 2011 12:10 am

Minimizing/eliminating allocations during Update?

Post by sqrtpi »

Hi, I'm looking for ways to minimize (preferably eliminate) allocations during BEPU update. Are the following things normal and am I approaching the solution correctly?

Heap memory is allocated on the following occasions:

Space.Add/Remove
Allocations occur on calls to space.Add/Remove. Taking a look at BEPU's code, there's object pooling going on, so I was expecting objects to be reused after a while; I'm not sure why it is allocating more each time. Is it normal and is it possible to avoid it?

My attempted solution is to create a pool for entities and add every entity to the space before-hand (on initialization). I haven't found an easy way to tell the space to "ignore" entities that aren't active (other than Removing it, is there such a property?) the best I've come up with is to zero-out all relevant properties (mass, velocity, momentum etc) and set it to not render on returning the entity to the pool, then re-initialize it when taking an entity from the pool.

This only partially works... allocations still occur for several space Updates for about a minute or two. After this (assuming no collisions) no more allocations occur and the heap size eventually settles on a number depending on how many objects I'm simulating. Is there a better way to pre-allocate objects in the space and/or avoid allocations during update?

Collisions
Every few collisions create allocations on the heap. From an earlier topic, I picked up the tip: pre-allocate NarrowPhaseFactory collision pairs. But even allocating about 500 ConvexConvex pairs ahead of time (plenty, in contrast to the ~20 collisions occurring every minute) hasn't prevented allocations from occurring every few collisions. Normal? can I prevent this?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Minimizing/eliminating allocations during Update?

Post by Norbo »

; I'm not sure why it is allocating more each time. Is it normal and is it possible to avoid it?
Allocating now and again may be normal and, for practical purposes, may be unavoidable. However, allocation alone is not a problem unless you are running out of memory. The question is if that allocated memory is garbage.

Does the garbage collector run repeatedly, taking away allocations created previously by the engine? What particular objects are being collected? Are they arrays from list resizing, or something else?
I haven't found an easy way to tell the space to "ignore" entities that aren't active (other than Removing it, is there such a property?)
Removing an object from the Space is the most complete removal. Other than that, there is deactivation through the deactivation manager, but if the object isn't supposed to be in the simulation, removing it from the Space entirely is the recommended approach.
Is there a better way to pre-allocate objects in the space and/or avoid allocations during update?
That depends on what is going on. There are some slightly more hidden pools laying here and there, such as in the broad phase. I don't have enough information to say for sure what should be done.
But even allocating about 500 ConvexConvex pairs ahead of time (plenty, in contrast to the ~20 collisions occurring every minute) hasn't prevented allocations from occurring every few collisions. Normal? can I prevent this?
That also depends on what exactly is going on. It could be normal, or not. Are the collision pairs actually all Convex-Convex pairs as opposed to Box-Box or Box-Sphere?

In order for me to provide more detailed information, I'll need some more information.

Are you primarily concerned with avoiding garbage collections, or are you worried about hitting memory limits? Or do you want to avoid heap complexity so unrelated garbage collections can run faster?

More importantly, a CLR-profileable reproduction case would be very useful to me in diagnosing the source of the allocations and determining recommended specific actions.
sqrtpi
Posts: 9
Joined: Tue Nov 22, 2011 12:10 am

Re: Minimizing/eliminating allocations during Update?

Post by sqrtpi »

Norbo wrote:Does the garbage collector run repeatedly, taking away allocations created previously by the engine? What particular objects are being collected? Are they arrays from list resizing, or something else?
The heap size is increasing; I can't tell if garbage is being collected, but the size doesn't noticeably ever decrease, so I assume not.
That also depends on what exactly is going on. It could be normal, or not. Are the collision pairs actually all Convex-Convex pairs as opposed to Box-Box or Box-Sphere?
In order for me to provide more detailed information, I'll need some more information.
So far I am only using ConvexHull shapes, but for good measure I also preallocated BoxBox pairs. The general flow of the demo is to generate a bunch of entities creating their collision bounds (ConvexHull) from the Model's vertices, then add them to the space and collide various groups of entities ("players", "projectiles", and "enemies").
My number one concern is to avoid the GC from running while the game is active (update/draw), but given that no new entities are ever generated beyond the Initialization phase, I'm thinking if there's a way to pre-allocate everything I need on Initialization, up-front, since I know ahead of time what I'll need.

Right now the project is part of a larger whole, I'll see if I can gut it some for a minimum test case.
sqrtpi
Posts: 9
Joined: Tue Nov 22, 2011 12:10 am

Re: Minimizing/eliminating allocations during Update?

Post by sqrtpi »

Hi, I've attached a very roughly gutted file with as much of the basics as I could retain. It missing a few things, but generally it still makes sense without it and can be swapped in with standard variants if you have them on hand (i.e. RenderingSystem, Pool, EntityModel, etc).

This version is using the object pooling, so the space.Add calls occur during creation of the pool, and Remove is never called. I apologize ahead of time for the hodgepodge code, it's the best that I could gut it. Happy to hear your thoughts/suggestions.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Minimizing/eliminating allocations during Update?

Post by Norbo »

I'm a little low on time at the moment; could you create a self-contained runnable project or modify it into a Demo runnable within the BEPUphysicsDemos please? :)
sqrtpi
Posts: 9
Joined: Tue Nov 22, 2011 12:10 am

Re: Minimizing/eliminating allocations during Update?

Post by sqrtpi »

I'll try to carry over as much as I can.
Post Reply