【问题标题】:Tuning OpenGL performance for geometry throughput针对几何吞吐量调整 OpenGL 性能
【发布时间】:2011-03-15 06:00:29
【问题描述】:

这可能已经被问了一遍又一遍,但我找不到任何有用的东西,所以又来了......

在我的应用程序中,我需要渲染一个相当大的网格(几百万个或更多三角形),但我在从中获得不错的帧速率时遇到了一些问题。 CPU 几乎处于空闲状态,所以我肯定受 GPU 限制。更改分辨率不会影响性能,因此它不受片段或光栅限制。

网格是动态的(但在本地是静态的),因此我无法将整个内容存储在视频卡中并一次调用即可渲染它。出于应用程序特定的原因,数据存储为叶子中带有体素的八叉树,这意味着我基本上可以免费进行视锥体剔除。顶点数据由坐标、法线和颜色组成 - 不使用纹理或着色器。

我的第一种方法是使用一个大的STREAM_DRAW VBO 从内存中渲染所有内容,结果证明这太慢了。我最初的想法是我可能使总线负担过重(每帧推约 150 MiB),所以我实现了一个缓存方案,该方案存储了最近用于在显卡上以静态 VBO 呈现对象的几何图形,每个 VBO 存储几个100 KiB 到几个 MiB 的数据(每个 VBO 存储更多会产生更多的缓存抖动,所以这里需要权衡)。下图是数据外观的示例,其中所有红色的内容都是从缓存的 VBO 中绘制的。


(来源:sourceforge.net

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

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

所以我的问题是如何加快速度?即:

  • 推荐的顶点格式是什么以获得良好的性能?我使用交错存储,位置和法线为GL_FLOATGL_UNSIGNED_BYTE 用于颜色,使用一个填充字节来获得 4 字节对齐(总共 28 个字节/顶点)。
  • 是否对我的所有盒子使用相同的法线缓冲区可能会有所帮助(所有盒子都是轴对齐的,因此我可以分配最大缓存条目大小的普通缓冲区并将其用于所有盒子)。
  • 我如何知道管道的哪一部分是瓶颈?我没有出色的显卡(带有开源 Linux 驱动程序的英特尔 GM965),所以我可能会达到它的极限。我可以从典型硬件(2-3 年的集成显卡、现代集成显卡、现代独立显卡)中获得多少吞吐量?
  • 有关如何解决此问题、陷阱等的任何其他提示。

我对建议 LOD(我已经测试过)、供应商特定提示或使用 1.5 之后的任何 OpenGL 功能的答案不感兴趣。

【问题讨论】:

  • 你的图元只包含在轴对齐的盒子里吗?
  • @Stringer Bell:是的(但不一定与世界轴对齐)。
  • 我不确定,但我猜你达到了显卡限制。我用谷歌搜索了一下,似乎英特尔 GM965 的性能相当低,尤其是在游戏方面。 (您的不是游戏,但渲染起来似乎相当“困难”)。 Nvidia有一个列表,他们的卡可以渲染多少个三角形/秒-也许你可以用这个列表对你的卡进行分类,以找出“理论”限制。
  • 您每帧进行多少次绘制调用?
  • @Andy J Buchanan:视情况而定,但在 50-150 左右。我可以调整这个,但到目前为止,允许更小的缓存条目(=> 更多的绘制调用)似乎提供了最好的吞吐量。

标签: opengl performance


【解决方案1】:

你可能不会喜欢这个回复......

我找到了您的问题:Intel GM965 与开源 Linux 驱动程序

虽然我目前的工作没有达到您的数据量,但我们已经在 VBO 中渲染了数百万个顶点,而英特尔图形硬件/驱动程序已被证明是无用的。给自己买一张 NVidia 卡(不必使用二进制驱动程序,它就可以工作),一切就绪。甚至不必是当前一代,尽管高端 Quadro(如果工作正在付费)或高端 GTX 400 系列(如果您正在付费或只是想在工作中节省一些钱)应该可以使用最新的司机。如果无法升级您的机器,您也可以尝试找一台带有此硬件的机器进行测试。

【讨论】:

  • 看来你是对的。我在具有更好图形的机器上进行了测试,不是 Quadro,但仍然更好,并获得了 15 Hz 的缓存和一半的没有缓存。与其说是问题,不如说是不便,因为我只是开发人员,而不是(目前)它的主要用户。
  • @Staffan:这并不意味着你的 GMA 965 对我来说是最大的。也许你只是在为表演做坏事。坦率地说,我会考虑尝试 Intel Media Accelerator Profiler(当然,如果您的应用程序是可移植的)。不要忘记 GMA 是基于图块的渲染器..
  • @Stringer Bell:看起来确实是视频卡/驱动程序设置了限制。在对我的缓存机制进行一些调整后,我在 GeForce 3 Ti200 上获得了大约 2800 万个三角形/秒,没有关于它可以推动多少个三角形的官方规范,但这似乎可能相当接近极限。
  • @Staffan:当然,你没有官方规范。你可以做的是检查像 3DMark 这样的基准测试:techreport.com/articles.x/12195/9你的应用程序的吞吐量是多少,以 MVertices/秒为单位?
  • 所有现有的基准测试都适用于这种情况,我只关心三角形/秒,而不关心着色器和其他东西。嗯,28 MTri/s = 28*3 = 84 MVertices/s
【解决方案2】:

我会首先使用性能分析器(如gDEBugger),这样您就可以确定您是否受顶点、片段或总线限制等。很难猜测在这种特殊情况下要执行哪些优化(Intel +开源驱动程序)。

您是否也尝试过 VA 模式?你在用glDrawElements吗? glDrawArrays?数据顶点缓存是否友好(转换前后)?​​

【讨论】:

  • Bell:如果有适用于 Linux 的开源(或免费)分析器,我会使用 OpenGL 分析器(请参阅my other question)。开源驱动程序是英特尔开发的官方驱动程序,但我想你已经知道了。我使用 glDrawArrays 因为我不能在顶点之间共享数据(所有顶点都有不同的法线或位置)。什么是VA模式?数据是缓存友好的 AFAICT,即交错存储(不确定转换会如何影响)。
  • 尽管是封闭源代码,但我尝试了 gDEBugger,但它对我不起作用(给我一个间接上下文,然后导致 SIGSEGV)。
  • VA 模式是普通的 1.1 顶点数组。仅当您有索引时才使用转换后缓存(请参阅opengl.org/wiki/Post_Transform_Cache)。你使用 GL_QUAD 还是 GL_TRIANGLES 来渲染你的盒子?
  • 你最好试试intel的东西:software.intel.com/en-us/articles/…
  • 啊,是的,我也用普通的 ol' 顶点数组进行了测试(我在上面发布了一些基准)。我用三角形。不幸的是,英特尔分析器仅适用于 Windows。
【解决方案3】:

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

当然,这取决于您更改数据的能力。如果真的和图片不一样,可能就不是这样了。

【讨论】:

  • 它们都是长方体,是的。正如我在 OP 中所描述的,我使用带有 VBO 的缓存来避免总线负担过重——生成上述图像时不涉及 glVertex3() 调用。
  • 但是 VBO != Display List... 不同的是 VBO 仍然使用 LARGE ARRAY,即使它在显存中。在大多数情况下,对于这样的设置,我得到最大的收益是调用 10000 x 一个 DL 即 10000 个立方体在一个顶点数组中。
猜你喜欢
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多