【发布时间】:2013-10-08 04:56:11
【问题描述】:
我正在努力掌握面向数据的设计以及如何在考虑缓存的情况下进行最佳编程。基本上有两种情况,我无法完全确定哪个更好以及为什么 - 拥有一个对象向量还是多个具有对象原子数据的向量更好?
A) 对象向量示例
struct A
{
GLsizei mIndices;
GLuint mVBO;
GLuint mIndexBuffer;
GLuint mVAO;
size_t vertexDataSize;
size_t normalDataSize;
};
std::vector<A> gMeshes;
for_each(gMeshes as mesh)
{
glBindVertexArray(mesh.mVAO);
glDrawElements(GL_TRIANGLES, mesh.mIndices, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
....
}
B) 带有原子数据的向量
std::vector<GLsizei> gIndices;
std::vector<GLuint> gVBOs;
std::vector<GLuint> gIndexBuffers;
std::vector<GLuint> gVAOs;
std::vector<size_t> gVertexDataSizes;
std::vector<size_t> gNormalDataSizes;
size_t numMeshes = ...;
for (index = 0; index++; index < numMeshes)
{
glBindVertexArray(gVAOs[index]);
glDrawElements(GL_TRIANGLES, gIndices[index], GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
....
}
哪一个更节省内存和缓存友好,从而导致更少的缓存未命中和更好的性能,为什么?
【问题讨论】:
-
你的结构看起来不够大,无法真正发挥作用,但如果它很大,我希望你的第一个选择有最少的失误
-
我在主机游戏编程中听说您应该尝试将相同类型的数据保持在附近(即第二种方法);像第一个这样的混合内容数据是一个禁忌。但我不确定该建议的相关性。
-
这不取决于访问模式吗?即,如果您只访问其中几个元素 - 但读取它们的所有数据 - 经常,第一个选项看起来更有希望,而如果您通常只使用一个成员变量,那么第二个看起来更好? (不过这只是猜测。)
-
建议你用opengl标记这个
-
你知道什么缓存效率更高吗?如果您使用
GL_UNSIGNED_SHORT作为索引数据类型。在 GPU 中,如果您的顶点少于 65537 个,则可以通过使用 16 位索引来提高 T&L 后缓存和标记的效率。您可能认为 8 位索引在逻辑上会为顶点数少于 257 的缓冲区进一步提高性能,但大多数硬件本身并不支持 8 位索引。
标签: c++ opengl caching memory-management data-oriented-design