I am writing a physics engine and having a hard time figuring out a good way to design my data storage.
The functionality that I want:
Right now I have basically two loops. One that updates the physics bodies in the simulation. It updates their position/velocity/rotation. The second loop performs collision detection over all the collision volumes. Its just a nested for loop that checks for collisions between each pair of collision volumes. (I know it can be done better but that's a separate topic)
I know that the ideal way is to store objects in contiguous arrays.
std::vector<PhysicsBody> m_bodies;
std::vector<CollisionVolume> m_colliders;
Problems I found with this approach:
I tried hard to find a way around it but ended up storing pointers instead:
std::vector<PhysicsBody*> m_bodies;
std::vector<CollisionVolume*> m_colliders;
The best solution to minimizing cache misses that I came up with was overloading new/delete and storing these objects in a memory pool just for the physics system.
Are there any other better solutions to this? Obviously performance is key.
A fundamental question: In the absence of threads running and modifying data from different cores(CPUs), where do you see the need to care about cache-coherency costs?
Cache-coherency protocol is triggered only when a line gets dirtied on a core different from the reader core or vice-versa.
It appears that you actually meant cache-locality? Is that right?
With the coherency Vs. locality out of the way, here is my take:
The moment you go to the vector, you lost direct control of managing locality. You can get back some of it by having a memory pool to draw from. Still, you would have to contend with relocation associated with resize operations.
Do you know the number of elements upfront? If yes, you can do this.
vector<T> myVec;
myVec.reserve(NUM_ELEMS);
followed by in-place new for each object from a contiguous area of memory.
myvec[i] = ...
The memory for the vector and the elements could entirely come from a single pool too. This can be achieved by passing in a custom allocator while instantiating the std::vector. Please see the following:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With