OpenGL低级性能问题

时间:2011-03-09 09:04:16

标签: performance optimization opengl sdl opengl-3

与任何优化问题一样,这个主题受到了很大的打击,但我找不到我想要的东西。

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

  • 使用GL面部剔除(OpenGL功能,而不是场景逻辑)
  • 仅向GPU发送1个矩阵(projectionModelView组合),因此将每个顶点的MVP计算减少到每个模型一次(应该如此)。
  • 使用交错顶点
  • 尽量减少尽可能多的总帐通话,并在适当情况下批量处理

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

虽然我在实施中收到大约40FPS,这绝不是问题,我仍然很好奇这些优化'技巧'实际上在哪里使用?

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

注意:我正在研究gDEBugger

交叉发布于Game Development

4 个答案:

答案 0 :(得分:25)

第1点显而易见,节省填充率也是如此。如果首先处理对象背面的基元,则将省略这些面。然而,现代GPU可以很好地容忍透支。我曾经(GeForce8800 GTX)在显着性能下降之前测量了高达20%的透支。但最好是保留这个储备,例如遮挡剔除,混合几何体的渲染等。

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

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

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

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

答案 1 :(得分:3)

  1. 没有任何意义,因为司机可以为你组合这些矩阵(它知道它们是制服,所以在抽签期间不会改变)。
  2. 仅当您受CPU限制时
  3. 您需要知道的第一件事就是您的瓶颈究竟在哪里。 GPU不是一个答案,因为它是一个复杂的系统。实际问题可能包括:

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

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

答案 2 :(得分:3)

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

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

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

另一件事是,当光栅化器在方形像素块上进行并行处理时,小三角形会产生填充;见http://www.geeks3d.com/20101201/amd-graphics-blog-tessellation-for-all/

答案 3 :(得分:1)

这在很大程度上取决于您运行的特定硬件以及使用场景。 OpenGL性能提示对于一般情况是有意义的 - 毕竟,库是许多不同驱动程序实现的抽象。   驱动程序制造商可以随心所欲地进行优化,因此他们可以在您不知情的情况下删除冗余状态更改或执行其他优化。在另一台设备上,他们可能没有。最好坚持使用最佳实践,以便在各种设备上获得更好的性能。