Got a license from Intel for VTune, thanks! First performance analysis showed unexpected slowdown due to island management. Added path-compression to UnionFind, and iterate just over island-id's, rather then all objects, when filling islands.

This commit is contained in:
Erwin Coumans 2006-08-29 23:27:27 +00:00
parent 069d8c45dc
commit bf49ff5050
4 changed files with 93 additions and 65 deletions

@ -116,7 +116,13 @@ void SimulationIslandManager::BuildAndProcessIslands(Dispatcher* dispatcher,Coll
int numBodies = collisionObjects.size(); int numBodies = collisionObjects.size();
for (int islandId=0;islandId<numBodies;islandId++) //first calculate the number of islands, and iterate over the islands id's
const UnionFind& uf = this->GetUnionFind();
for (int islandId=0;islandId<uf.getNumElements();islandId++)
{
if (uf.isRoot(islandId))
{ {
std::vector<PersistentManifold*> islandmanifold; std::vector<PersistentManifold*> islandmanifold;
@ -153,11 +159,12 @@ void SimulationIslandManager::BuildAndProcessIslands(Dispatcher* dispatcher,Coll
CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0()); CollisionObject* colObj0 = static_cast<CollisionObject*>(manifold->GetBody0());
CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1()); CollisionObject* colObj1 = static_cast<CollisionObject*>(manifold->GetBody1());
assert(colObj0);
assert(colObj1);
{ {
if (((colObj0) && (colObj0)->m_islandTag1 == (islandId)) || if (((colObj0)->m_islandTag1 == (islandId)) ||
((colObj1) && (colObj1)->m_islandTag1 == (islandId))) ((colObj1)->m_islandTag1 == (islandId)))
{ {
if (dispatcher->NeedsResponse(*colObj0,*colObj1)) if (dispatcher->NeedsResponse(*colObj0,*colObj1))
islandmanifold.push_back(manifold); islandmanifold.push_back(manifold);
} }
@ -201,3 +208,4 @@ void SimulationIslandManager::BuildAndProcessIslands(Dispatcher* dispatcher,Coll
} }
} }
} }
}

@ -24,6 +24,12 @@ int UnionFind::find(int x)
while (x != m_id[x]) while (x != m_id[x])
{ {
//not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
#define USE_PATH_COMPRESSION 1
#ifdef USE_PATH_COMPRESSION
//
m_id[x] = m_id[m_id[x]];
#endif //
x = m_id[x]; x = m_id[x];
assert(x < m_N); assert(x < m_N);
assert(x >= 0); assert(x >= 0);
@ -89,6 +95,8 @@ void UnionFind ::unite(int p, int q)
int i = find(p), j = find(q); int i = find(p), j = find(q);
if (i == j) if (i == j)
return; return;
//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
if (m_sz[i] < m_sz[j]) if (m_sz[i] < m_sz[j])
{ {
m_id[i] = j; m_sz[j] += m_sz[i]; m_id[i] = j; m_sz[j] += m_sz[i];

@ -17,6 +17,8 @@ subject to the following restrictions:
#define UNION_FIND_H #define UNION_FIND_H
///UnionFind calculates connected subsets ///UnionFind calculates connected subsets
// Implements weighted Quick Union with path compression
// optimization: could use short ints instead of ints (halving memory, would limit the number of rigid bodies to 64k, sounds reasonable)
class UnionFind class UnionFind
{ {
private: private:
@ -32,6 +34,15 @@ class UnionFind
void reset(int N); void reset(int N);
inline int getNumElements() const
{
return m_N;
}
inline bool isRoot(int x) const
{
return (x == m_id[x]);
}
int find(int p, int q); int find(int p, int q);
void unite(int p, int q); void unite(int p, int q);

@ -41,6 +41,7 @@ class PersistentManifold;
class BroadphaseInterface; class BroadphaseInterface;
class OverlappingPairCache; class OverlappingPairCache;
class IDebugDraw; class IDebugDraw;
class PHY_IVehicle;
/// CcdPhysicsEnvironment is experimental mainloop for physics simulation using optional continuous collision detection. /// CcdPhysicsEnvironment is experimental mainloop for physics simulation using optional continuous collision detection.
/// Physics Environment takes care of stepping the simulation and is a container for physics entities. /// Physics Environment takes care of stepping the simulation and is a container for physics entities.
@ -135,7 +136,7 @@ protected:
); );
virtual void `straint(int constraintid); virtual void removeConstraint(int constraintid);
virtual float getAppliedImpulse(int constraintid); virtual float getAppliedImpulse(int constraintid);