如何优化 VBO/IBO 以最大化 GPU 缓存使用率
Posted
技术标签:
【中文标题】如何优化 VBO/IBO 以最大化 GPU 缓存使用率【英文标题】:How to Optimizing a VBO/IBO to maximize GPU cache usage 【发布时间】:2015-09-22 21:54:18 【问题描述】:我正在使用在 CUDA 上运行的 Marching Cubes 算法从体积数据生成网格。
我尝试过保存网格并以 3 种方式渲染它。
-
将一组粗略的三角形保存为顶点数据的连续数组。
如果第一次通过,我估计大小,创建一个 OpenGL VBO,
将其映射到 CUDA 并按以下格式将顶点数据写入其中
V0x, V0y, V0z, N0x, N0y, N0z, V1x, V1y, V1z, N1x, N1y, N1z, ...
并使用glDrawArrays()
绘制它。
VBO 中的冗余顶点,每个立方体的冗余顶点,无索引。
-
从步骤 1 中获取网格,使用
thrust::sort()
和 thrust::unique()
删除冗余顶点,使用 thrust::lower_bound()
计算索引。将结果保存到映射到 CUDA 的 OpenGL VBO/IBO。
使用glDrawElements()
绘制模型。
VBO 中没有冗余顶点,生成索引。
-
为每个立方体生成一个唯一的顶点列表,将它们连同在 IBO 中形成三角形的索引一起存储在 VBO 中。使用
glDrawElements()
渲染。
VBO 中的冗余顶点、每个立方体的唯一顶点、每个立方体生成的索引
现在我在相同 ISO-Value ` 下获得的相同数据集的 FPS 是
Method 1 : 92 FPS, 30,647,016 Verts, 0 Indices
Method 2 : 122 FPS, 6,578,066 Verts, 30,647,016 Indices
Method 3 : 140 FPS, 20,349,880 Verts, 30,647,016 Indices
即使方法 2 产生的顶点数量最少,FPS 也很低。我相信这是因为索引的顺序可以最大限度地减少 GPU 缓存的使用。方法 3 的索引顺序获得更高的 GPU 缓存使用率,因此 FPS 更高。
如何修改/修改方法 2 以产生更高的 FPS?
【问题讨论】:
你的 FPS 测量方法是否考虑到使用推力去除冗余顶点所需的时间? @m.s.删除只进行一次。我不是在寻找实时删除方法。当 iso 值发生变化时,我只是在方法 1 中渲染粗网格。一旦变化保持不变,我就会处理大约需要 4 秒的移除。之后我只使用 VBO/IBO 来渲染网格。我希望这个网格有更高的 FPS,而只是渲染,当我测量 FPS 时不进行提取或压缩。 【参考方案1】:有两件事可以提供帮助:
尝试通过将顶点大致按照绘制它们的顺序来优化数据缓存的使用 正在尝试优化post transform cache 的使用(here 有一个算法可以做到这一点,网上可能可以找到实现)【讨论】:
谢谢@Jerem,我会试试这个算法Fast Vertex Cache Opt。将更新结果如何。我想找到一些使用尽可能少内存的算法,因为我的网格尺寸往往会变得非常大。 尝试了上述算法的 CPU 实现,它可以工作,但速度太慢。 60K 网格需要超过 12 秒,我的网格超过 20M,对于这种尺寸的网格来说是不可行的。正在寻找一种可扩展到 GPU 的解决方案。 您是否尝试按照绘制顺序对顶点进行排序? 嗯,是的,我在排序数百万个顶点时遇到了其他问题。如果我在 GPU 上执行它并且在 CPU 上太慢,我会遇到内存限制。但是你的答案是正确的以获得最佳的缓存命中率,但是由于网格大小,我将它用于我的应用程序是不可行的。不过我会接受这个答案。谢谢。 答案包含死链接。以上是关于如何优化 VBO/IBO 以最大化 GPU 缓存使用率的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO