VBO何时比“简单”OpenGL原语(glBegin())更快?

时间:2009-01-10 04:29:24

标签: performance opengl graphics vbo vertex-buffer

经过多年关于顶点缓冲对象(VBO)的讨论,我终于决定尝试它们(我的东西通常不是性能关键,显然......)

我将在下面描述我的实验,但长话短说,我看到“简单”直接模式(glBegin()/ glEnd()),顶点数组(CPU端)和VBO之间无法区分性能( GPU侧)渲染模式。我试图理解为什么会这样,并且在什么条件下我可以期待看到VBO明显优于他们原始(双关语)的祖先。

实验细节

对于实验,我生成了一个具有大量点的(静态)3D高斯云。每个点都有顶点和顶点。与之相关的颜色信息。然后我在连续的帧中围绕云旋转相机,这是一种“轨道”行为。同样,这些点是静态的,只有眼睛移动(通过gluLookAt())。数据在任何渲染之前生成一次。存储在两个数组中以用于渲染循环。

对于直接渲染,整个数据集在单个glBegin()/ glEnd()块中呈现,其中包含一个循环,每个循环包含glColor3fv()和glVertex3fv()。

对于顶点数组和VBO渲染,整个数据集使用单个glDrawArrays()调用进行渲染。

然后,我只需在紧凑的循环中运行一分钟左右,并使用高性能计时器测量平均FPS。

表现结果##

如上所述,我的台式机(XP x64,8GB RAM,512 MB Quadro 1700)和笔记本电脑(XP32,4GB RAM,256 MB Quadro NVS 110)的性能难以区分。然而,它确实按照预期的点数进行了扩展。显然,我也禁用了vsync。

笔记本电脑运行的具体结果(使用GL_POINTS渲染):

在glBegin()/ glEnd():

  • 1K pts - > 603 FPS
  • 10K分 - > 401 FPS
  • 100K分 - > 97 FPS
  • 1M分 - > 14 FPS

顶点阵列(CPU端):

  • 1K pts - > 603 FPS
  • 10K分 - > 402 FPS
  • 100K分 - > 97 FPS
  • 1M分 - > 14 FPS

顶点缓冲区对象(GPU侧):

  • 1K pts - > 604 FPS
  • 10K分 - > 399 FPS
  • 100K分 - > 95 FPS
  • 1M分 - > 14 FPS

我使用GL_TRIANGLE_STRIP渲染了相同的数据并且得到了类似的无法区分(尽管由于额外的光栅化而预期速度较慢)。如果有人想要,我也可以发布这些数字。  

问题(S)

  • 给出了什么?
  • 我需要做些什么才能实现VBO承诺的性能提升?
  • 我缺少什么?

6 个答案:

答案 0 :(得分:27)

优化3D渲染有很多因素。 通常有4个瓶颈:

  • CPU(创建顶点,APU调用,其他所有内容)
  • 总线(CPU< - > GPU传输)
  • 顶点(固定功能管道执行时的顶点着色器)
  • 像素(填充,片段着色器执行和rops)

您的测试结果不正确,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线)。 VBO用于降低CPU(更少的api调用,与CPU DMA传输并行)。由于您不受CPU限制,因此它们不会给您带来任何好处。这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是用于发出大量的api调用。很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期。

答案 1 :(得分:10)

可能缺少一些东西:

  1. 这是一个疯狂的猜测,但你的笔记本电脑的卡可能完全没有这种操作(即模仿它)。

  2. 您是否正在将数据复制到GPU的内存中(通过glBufferDataGL_ARRAY_BUFFER使用GL_STATIC_DRAWGL_DYNAMIC_DRAW参数)或使用指向main的指针(内存中的非GPU数组?(需要每帧复制一次,因此性能很慢)

  3. 您是否将 indices 作为另一个通过glBufferDataGL_ELEMENT_ARRAY_BUFFER参数发送的缓冲区传递?

  4. 如果完成这三件事,性能提升很大。 对于Python(v / pyOpenGl),它比大于100个元素的数组大约快1000倍, C ++的速度提高了5倍,但在50k-10m的顶点阵列上。

    以下是我对c ++(Core2Duo / 8600GTS)的测试结果:

     pts   vbo glb/e  ratio
     100  3900  3900   1.00
      1k  3800  3200   1.18
     10k  3600  2700   1.33
    100k  1500   400   3.75
      1m   213    49   4.34
     10m    24     5   4.80
    

    因此,即使有10米的顶点,它也是正常的帧率,而使用glB / e则是缓慢的。

答案 2 :(得分:4)

作为旁注:
以下不支持“直接模式”(glBegin / glEnd):

  • OpenGLES。
  • OpenGL 3.x。
  • 因此,如果您计划将应用程序移植到移动平台(例如iPhone), 甚至不习惯它。

    我在大学教OpenGL,幻灯片解释glBegin / glEnd有一个大红框 它带有一个额外的粗体“请勿使用”标题。

    使用顶点数组只需要两行,您可以从一开始就保存周期。

    答案 3 :(得分:2)

    通过阅读红皮书,我记得有一段话说VBO可能更快取决于硬件。一些硬件优化了这些,而其他硬件没有。您的硬件可能没有。

    答案 4 :(得分:1)

    14Mpoints / s不是很多。这是可疑的。我们能看到完整的代码进行绘图,以及初始化吗? (比较那个14M / s到Slava Vishnyakov获得的240M / s(!))。更令人怀疑的是,1K平均下降到640K / s(与他的3.8M / s相比,无论如何都被~3800 SwapBuffers限制)。

    我正在测试不会衡量你认为它的衡量标准。

    答案 5 :(得分:-3)

    假设我记得这一点,我在OpenGL社区中众所周知的OpenGL老师说,他们在静态几何上的速度更快,这将在典型的游戏中渲染很多时间,这将是桌椅和小静态实体。