假设我有一个由顶点组成的模型,每个顶点具有positionnormaltangenttexcoord属性,其中三角形由索引三元组指定。如果我们只关注顶点属性,我了解两种广泛的策略:数组的结构和结构的数组。我还听说结构数组是首选的,因为它增加了给定顶点的属性的内存局部性(并因此提高了高速缓存局部性)。我可以想到的主要方式是通过顶点索引,该索引要求光栅化器获取早已从缓存中逐出的顶点数据。如果这样的顶点数据访问是随机的,那么将顶点的所有属性都保留在同一条缓存行上肯定会使事情变得更快,但这不是可以通过优化三角形规格的顺序来缓解的一个问题吗?

此外,据我了解,现代GPU在解压缩相同类型的长向量上可能比许多类型的结构的向量更好。如果优化了索引顺序,那么数组结构布局是否能够始终胜过相同顶点数据的结构数组布局?

评论

您不能简单地尝试一下,看看哪种方法最适合您的情况?

我本来认为对于索引网格来说,结构数组会更有效,因为顶点着色器将获得所有顶点属性,因此将它们组合到内存中将对缓存更友好。
根据结构中的数据类型,vec4s和float会很好地打包在一起,其他类型则不太好

@ user1118321虽然单个基准测试实验是值得赞扬的实践,但在更广泛的理论讨论中当然还有更多的长期价值,并且可能会基于顶点牵引硬件的工作原理而建立通用实践。

#1 楼

抱歉,我要在您的问题线程中添加评论,但发现我最终花了太多时间。我的开发经验是从DX 11角度出发的,因此其中某些可能无法在OpenGL中使用。

数据的内存局部性无疑起着重要的作用。但是,还有其他一些因素会影响数据的宽度。我有一些GPU,并且在某些临界点的基础上,性能却出现了明显下降。举例来说,例如,在我的旧AMD r290上,您基本上可以将多达4个float4传递到顶点缓冲区,而不会花费超过1的额外费用,但是一旦我发布> 4,则存在可测量的下降率)。这纯粹是我的回忆,所以轶事也是最好的。但是它认为GPU架构一直在变化,今天能为您带来性能优势的利基技术可能是明天性能的祸根。我已经尝试过最好的建议,即硬件供应商将通过最常见的技术通过VB传递有效负载来构建GPU(显然,它们来自常量缓冲区)。

话虽如此,您已经提出了有关对顶点进行排序的问题,当然这会有所帮助。当您将其与索引缓冲区结合使用时,性能将得到提高,从而使硬件能够优化并缓存已计算的顶点。当然,您可以从三角带等中获得更多收益,这些三角带可以根据您的想法专门订购。我所做的大多数模型渲染都是基于实例的基于索引/顶点的优化模型,我对循环运动效果(例如,树枝)使用少量查找,在这些情况下,树的整个分支都在查找相同的值。因此,缓存也可以在这里利用。

我可以总结一下:在开始开发游戏/应用程序时,请不要一开始就过多考虑优化问题,而不要过早优化。如果您需要返回并添加新功能,则可能会花费所有精力。您有我的习惯,也许> <,喜欢尝试获得最佳性能和技术
GPU架构千差万别,其中一种优势可以反映另一种优势。 AMD和Nvidia以让开发人员针对其架构优化游戏而闻名,这在一定程度上有其优点/缺点。在开发中走中间路可能是最好的地方,不要使用任何基于硬件供应商的功能(此处有意见)。 (此外,某些打包格式仅在AMD中存在。)

这些只是我的一些想法和经验。那里有很多书,您应该着手解决这些主题。我还没有看到很多规定您要提出的建议,但这并不意味着错误。祝你好运。

#2 楼

这可能取决于目标硬件和将要使用的API。您可以提供更多信息吗?这是OpenGL的一些(非常广泛和通用的)最佳实践。还是您只是好奇。