21

与任何优化问题一样,这个主题受到了很多关注,但我就是找不到我(认为)我想要的东西。

很多教程,甚至SO问题都有类似的提示;一般涵盖:

  • 使用 GL 面剔除(OpenGL 函数,不是场景逻辑)
  • 仅将 1 个矩阵发送到 GPU(projectionModelView 组合),因此将 MVP 计算从每个顶点减少到每个模型一次(应该如此)。
  • 使用交错顶点
  • 尽可能减少 GL 调用,在适当的地方进行批处理

可能还有一些/许多其他人。我(出于好奇)使用多个顶点缓冲区在我的应用程序中渲染 2800 万个三角形。我已经尝试了上述所有技术(据我所知),几乎没有收到任何性能变化。

虽然我在实现中收到大约 40FPS,这绝不是问题,但我仍然很好奇这些优化“提示”实际上在哪里使用?

我的 CPU 在渲染过程中闲置了大约 20-50%,因此我假设我受制于 GPU 以提高性能。

注意:我现在正在研究 gDEBugger

交叉张贴在游戏开发

4

4 回答 4

26

第 1 点很明显,因为它可以节省填充率。如果首先处理对象背面的图元,这将省略这些面。然而,现代 GPU 可以很好地容忍过度绘制。我曾经(GeForce8800 GTX)测量过高达 20% 的透支,然后才显着影响性能。但最好将此保留用于遮挡剔除、混合几何体的渲染等。

第2点,毫无意义。这些矩阵从未在 GPU 上计算过——好吧,如果你不计算 SGI Onyx 的话。矩阵一直只是在 CPU 上计算的某种渲染全局参数,然后推入 GPU 上的全局寄存器,现在称为统一,因此加入它们只有很少的好处。在仅保存一个额外的向量矩阵乘法(归结为 4 个 MAD 指令)的着色器中,以降低算法灵活性为代价。

第 3 点是关于缓存效率的。属于一起的数据应该适合缓存行。

第 4 点是关于防止状态更改破坏缓存。但这在很大程度上取决于他们所说的 GL 的意思。换制服很便宜。切换纹理是昂贵的。原因是,制服位于寄存器中,而不是缓存中的某块内存。切换着色器的成本很高,因为不同的着色器表现出不同的运行时行为,从而破坏了管道执行的预测,改变了内存(并因此)改变了缓存访问模式等等。

但这些都是微观优化(其中一些影响巨大)。但是,我建议查看大型影响优化,例如实施早期 Z 通道;在早期 Z 中使用遮挡查询来快速区分整个几何批次。一个大的影响优化,本质上包括总结很多 Point-4 之类的微优化,是按昂贵的 GL 状态对渲染批次进行排序。因此,使用通用着色器将所有内容分组,在这些组中按纹理排序等等。这种状态分组只会影响可见的渲染通道。在早期 Z 中,您只在 Z 缓冲区上测试结果,因此只有几何变换,片段着色器只会传递 Z 值。

于 2011-03-09T10:31:46.860 回答
3
  1. 是的
  2. 没有意义,因为驱动程序可以为您组合这些矩阵(它知道它们是统一的,因此在绘图调用期间不会改变)。
  3. 是的
  4. 仅当您受 CPU 限制时

您需要知道的第一件事是您的瓶颈到底在哪里。GPU 不是答案,因为它是一个复杂的系统。实际的问题可能在这些之中:

  • 着色器处理(顶点/片段/几何)
  • 填充率
  • 抽签电话号码
  • GPU <-> VMEM(这就是交错和更小的纹理有帮助的地方)
  • 系统总线(每帧传输一些数据?)

您需要执行一系列测试才能看到问题。例如,将所有内容绘制到更大的 FBO 以查看是否是填充率问题(或增加 MSAA 数量)。或者将所有内容绘制两次以检查绘制调用过载问题。

于 2011-03-09T23:35:03.703 回答
3

只是为了将我的 2 美分添加到 @kvark 和 @datenwolf 的答案中,我想说的是,虽然您提到的要点是“基本”GPU 性能提示,但更多涉及的优化非常依赖于应用程序。

在您的几何繁重的测试用例中,您已经在每秒抛出 2800 万个三角形 * 40 FPS = 11.2 亿个三角形 - 这已经相当多:大多数(不是全部,尤其是 Fermi)GPU 的三角形设置性能为每个 GPU 时钟周期 1 个三角形。这意味着以 800MHz 运行的 GPU 每秒不能处理超过 8 亿个三角形;这甚至没有绘制一个像素。NVidia Fermi 每个时钟周期可以处理 4 个三角形。

如果你达到了这个限制(你没有提到你的硬件平台),那么你在 OpenGL/GPU 级别上无能为力。您所能做的就是发送更少的几何图形,通过更有效的剔除(平截头体或遮挡)或通过 LOD 方案。

另一件事是,当光栅化器对方形像素块进行并行处理时,微小的三角形会损害填充率。请参阅http://www.geeks3d.com/20101201/amd-graphics-blog-tessellation-for-all/

于 2011-03-11T08:06:38.287 回答
1

这在很大程度上取决于您正在运行的特定硬件以及使用场景。OpenGL 性能提示对于一般情况是有意义的——毕竟,该库是对许多不同驱动程序实现的抽象。驱动程序制造商可以自由地优化他们想要的引擎盖,因此他们可能会在您不知情的情况下删除多余的状态更改或执行其他优化。在另一台设备上,他们可能不会。最好坚持最佳实践,以便在一系列设备上获得更好的性能。

于 2011-03-09T11:44:26.327 回答