调整OpenGL性能以提高几何吞吐量

15

这个问题可能一而再、再而三地被问到,但我没找到什么有用的信息,所以我再次提出它...

在我的应用程序中,我需要呈现一个相当大的网格(几百万个三角形或更多),但是我在获取良好的帧速率方面遇到了一些问题。CPU几乎处于空闲状态,因此我明显受限于GPU。更改分辨率不影响性能,因此它不是片段或栅格化限制。

该网格是动态的(但局部静态),因此无法将整个网格存储在视频卡中,并使用单个调用进行呈现。由于应用程序特定原因,数据存储为八叉树,并在叶子节点上使用体素,这意味着我基本上可以免费获得视锥体裁剪。顶点数据包括坐标,法线和颜色-不使用纹理或着色器。

我的第一种方法是使用一个大的STREAM_DRAW VBO从内存中呈现所有内容,结果速度太慢。我的初始想法是我可能过度使用总线(每帧推送约150 MiB),因此我实施了一个缓存方案,将最近用于呈现对象的几何体存储在图形卡的静态VBO中,每个VBO存储几百KiB到几MiB的数据(存储更多每个VBO会导致更多的缓存抖动,因此在此处存在权衡)。下面的图片是数据外观的示例,在这个示例中,所有红色的东西都是从缓存的VBO中绘制的。

渲染数据的示例
(来源:sourceforge.net

如下所示的数字表明,当使用缓存时,我没有看到性能显著提高。对于大约100万个三角形的完全静态网格,我得到以下帧速率:

  • 不使用缓存:1.95 Hz
  • 使用顶点数组进行缓存:2.0 Hz(> 75%的网格已被缓存)
  • 使用STATIC_DRAW VBO进行缓存:2.4赫兹

我的问题是如何加速?即:

  • 什么是建议的顶点格式以获得良好的性能?我使用交替存储,位置和法线为GL_FLOAT,颜色为GL_UNSIGNED_BYTE,其中一个填充字节以获得4字节对齐(总共28字节/顶点)。
  • 是否为所有的盒子都使用相同的法线缓冲区可能会有帮助(所有的盒子都是轴对齐的,所以我可以分配一个最大缓存条目大小的法线缓冲区,并将其用于它们所有的盒子)。
  • 如何知道管道的哪个部分是瓶颈?我的显卡不是很好(Intel GM965与开源Linux驱动程序),因此我可能达到了它的极限。从典型硬件(2-3年前的集成图形,现代集成图形,现代离散图形)可以期望多少吞吐量?
  • 您如何处理此问题的任何其他提示,陷阱等。

我不感兴趣的答案包括LOD(我已经测试过了),供应商特定的提示或使用OpenGL功能,来自任何晚于1.5的版本。


你的基元是否仅限于轴对齐的盒子? - elmattic
@Stringer Bell:是的(但不一定与世界坐标轴对齐)。 - Staffan
1
我不确定,但我猜测你达到了显卡的极限。我已经上网搜索了一下,似乎Intel GM965的性能相当低,尤其是对于游戏而言(虽然你的项目不是游戏,但看起来似乎很难渲染)。Nvidia有一个列表,可以显示他们的卡每秒能够渲染多少个三角形 - 也许你可以用这个列表将你的卡分类,找出它的“理论”极限。 - InsertNickHere
每帧你执行了多少次绘制调用? - Andy J Buchanan
@Andy J Buchanan:这取决于情况,但大约在50-150之间。我可以进行调整,但到目前为止,允许较小的缓存条目(=>更多绘制调用)似乎能够提供最佳吞吐量。 - Staffan
3个回答

5

恐怕我的回答不太能让您满意。

我找到了您的问题所在:使用 Intel GM965 和开源 Linux 驱动程序。

即使当前我的工作量没有你那么大,但我们曾经在 VBO 中渲染过数百万个顶点,而 Intel 的图形硬件/驱动程序已经被证明是无用的。您需要一张 Nvidia 显卡(并且不要介意使用二进制驱动程序,它可以正常工作),这样您就可以解决问题了。即使不是最新一代的显卡也可以,只需要一张高端 Quadro(如果公司付钱)或者高端 GTX 400 系列(如果您自己付钱或者想在公司省些钱)和最新的驱动程序就可以了。如果无法升级您的机器,您还可以尝试找一台带有这种硬件的机器进行测试。


看起来你是对的。我在一台图形更好的机器上进行了测试,虽然不是Quadro但仍然更好,使用缓存时得到了15 Hz,没有使用缓存时只有一半的速度。这更多是一个不便而不是问题,因为我只是开发人员,目前不是主要用户。 - Staffan
@Staffan:这并不意味着您已经使GMA 965达到最大化。也许您只是做了一些影响性能的事情。坦率地说,如果您的应用程序是可移植的话,我会考虑使用Intel Media Accelerator Profiler。别忘了GMA是基于平铺的渲染器... - elmattic
@Stringer Bell:看起来确实是显卡/驱动程序设置了限制。在调整了我的缓存机制后,我在GeForce 3 Ti200上获得了约2800万个三角形/秒的速度,虽然没有官方规格说明它可以推动多少三角形,但这似乎已经相当接近极限了。 - Staffan
@Staffan:当然,你没有官方规格。你可以做的是像3DMark这样的基准测试:http://techreport.com/articles.x/12195/9 你的应用程序吞吐量是多少M顶点/秒? - elmattic
所有现有的基准测试都太宽泛了,我只关心三角形/秒,而不是着色器等其他内容。好吧,28 MTri/s = 28 * 3 = 84 MVertices/s。 - Staffan

0
我会先使用性能分析器(例如gDEBugger),以便您可以确定您是顶点、片段还是总线受限等。在这种特殊情况下(Intel + 开源驱动程序),很难猜测要执行哪些优化。
您是否也尝试过VA模式?您正在使用glDrawElements吗?glDrawArrays?数据是否对顶点缓存友好(变换前和变换后)?

Bell:如果有一个开源(或免费)的OpenGL分析器适用于Linux,我会使用它(请参见我的另一个问题)。开源驱动程序是由英特尔开发的官方驱动程序,但我想你已经知道了。我正在使用glDrawArrays,因为我不能在顶点之间共享数据(所有顶点都具有不同的法线或位置)。什么是VA模式?据我所知,数据是缓存友好的,即交错存储(不确定转换会如何影响它)。 - Staffan
我尝试了一下gDEBugger,虽然它是闭源的,但它对我没有用(给我一个间接的上下文,然后导致SIGSEGV)。 - Staffan
VA模式是普通的1.1顶点数组。只有在使用指数时才使用后变换缓存(请参见http://www.opengl.org/wiki/Post_Transform_Cache)。您在呈现框时使用GL_QUAD还是GL_TRIANGLES? - elmattic
你最好尝试英特尔的东西:http://software.intel.com/en-us/articles/intel-graphics-media-accelerator-profiler-v21/ - elmattic
啊,是的,我也测试了普通的顶点数组(我在上面发布了一些基准测试)。我使用三角形。不幸的是,英特尔分析器仅适用于Windows操作系统。 - Staffan

0

我不知道你的“网格”是什么,但它们似乎都是立方体。如果可能的话,将单个联合立方体渲染到显示列表中,并渲染该显示列表的缩放版本。这通常可以提高10倍的速度,因为总线不会被顶点数据填充或视频内存耗尽。

当然,这取决于您更改数据的能力。如果它确实不像图片上那样,那么情况可能并非如此。


它们都是长方体,没错。正如我在原帖中所描述的那样,我使用带有VBO缓存的方法来避免过度使用总线——上面的图像生成过程中没有涉及任何glVertex3()调用。 - Staffan
但是VBO!=显示列表...区别在于,即使它在视频内存中,VBO仍然使用大数组。在大多数情况下,对于像这样的设置,我通过调用10000个DL来获得最大的效益,而不是使用顶点数组中的10000个立方体。 - rioki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接