Nix*_*ixt 6 c++ performance memory-management game-physics data-oriented-design
我正在编写物理引擎,并且很难找到设计数据存储的好方法.
我想要的功能:
现在我基本上有两个循环.一个更新模拟中的物理实体.它会更新它们的位置/速度/旋转.第二个循环对所有碰撞体积执行碰撞检测.它只是一个嵌套的for循环,用于检查每对碰撞体积之间的碰撞.(我知道它可以做得更好,但这是一个单独的主题)
我知道理想的方法是将对象存储在连续的数组中.
std::vector<PhysicsBody> m_bodies;
std::vector<CollisionVolume> m_colliders;
Run Code Online (Sandbox Code Playgroud)
我用这种方法发现的问题:
我努力寻找解决方法,但最终存储了指针:
std::vector<PhysicsBody*> m_bodies;
std::vector<CollisionVolume*> m_colliders;
Run Code Online (Sandbox Code Playgroud)
我想出的最小化缓存未命中的最佳解决方案是重载新/删除并将这些对象存储在内存池中,仅用于物理系统.
还有其他更好的解决方案吗?显然,表现是关键.
一个基本问题:在没有线程运行和修改来自不同内核(CPU)的数据的情况下,您认为有必要关心缓存一致性成本吗?
仅当与读取器核心不同的核心上的线路变脏时才会触发缓存一致性协议,反之亦然。
看来您实际上是指缓存局部性?是对的吗?
与一致性对比。地方不碍事,这是我的看法:
当您进入向量时,您就失去了对管理位置的直接控制。您可以通过使用内存池来取回其中的一部分。尽管如此,您仍然必须应对与调整大小操作相关的重定位问题。
您预先知道元素的数量吗?如果是,你可以这样做。
vector<T> myVec;
myVec.reserve(NUM_ELEMS);
Run Code Online (Sandbox Code Playgroud)
接下来是来自连续内存区域的每个对象的就地 new。
myvec[i] = ...
Run Code Online (Sandbox Code Playgroud)
向量和元素的内存也可以完全来自单个池。这可以通过在实例化 std::vector 时传入自定义分配器来实现。请参阅以下内容: