【问题标题】:glDrawElements massive cpu usage on iOS在 iOS 上 glDrawElements 大量 cpu 使用
【发布时间】:2014-10-18 05:42:41
【问题描述】:

硬件:iPad2 软件:OpenGL ES 2.0 C++

glDrawElements 似乎占用了大约 25% 的 cpu。使 CPU 18ms 和 GPU 10ms 每帧。

当我不使用索引缓冲区并使用 glDrawArrays 时,它会加速并且 glDrawArrays 大麦会显示在分析器上。其他一切都一样,glDrawArrays 有更多顶点,因为我必须在没有索引缓冲区的情况下复制 VBO 中的顶点。

到目前为止:

  • 两种方法之间的状态变化量几乎相同
  • 顶点结构是两个浮点数(8字节)。
  • indexbuffer 是 16bit(也试过 32bit)
  • 两个缓冲区的 GL_SATIC_DRAW
  • 加载后缓冲区不会改变
  • 相同的 VBO 和 indexbuffer 每帧渲染多次,具有不同的偏移量和大小
  • 没有 opengl 错误

所以它看起来像是在做某种软件后备。但我不知道是什么导致 OpenGL 回退。

【问题讨论】:

    标签: ios iphone ipad opengl-es opengl-es-2.0


    【解决方案1】:

    有几件事会立即浮现在脑海中,可能会影响您描述的速度。

    一方面,许多命令是被动发出的,以减少总线传输的次数。他们排队等待下一批转移。状态变化、纹理变化和类似的命令都会累积。绘图命令可能会在一种情况下触发更大的传输,但在另一种情况下不会,或者您在一种情况或另一种情况下触发更频繁的传输。另一方面,您的特定模型可能会更好地组织一个或另一个绘图调用。您需要查看它们有多大,它们是否重用索引值,以及它们是否针对渲染进行了优化或重新排序。 glDrawArrays 可能需要传输更多数据,但如果您的模型很小,则开销可能不是太大问题。绘制频率变得很重要,因为您希望频繁排队调用以保持卡忙碌并让您的 CPU 做其他工作,您不希望它只是累积在等待发送的命令缓冲区中,但它需要平衡,因为这些转移是有成本的。最重要的是,频繁索引的值在频繁重用时可以从缓存效应中受益,但线性访问的数组在线性访问时可以从缓存效应中受益,因此您需要了解您的数据,因为不同类型的数据受益于不同的数据方法。

    就连 Apple 似乎也不确定使用哪种方法。

    直到 iOS7,该版本及更早版本的OpenGL ES Programming Guide for IOS 写道:

    为获得最佳性能,您的模型应使用 glDrawArrays 提交为单个未索引的三角形带,并尽可能少地重复顶点。如果您的模型需要重复许多顶点 (...),您可以使用单独的索引缓冲区并改为调用 glDrawElements 来获得更好的性能。 ... 为获得最佳结果,请同时使用索引和未索引的三角形带测试您的模型,并使用性能最快的。

    但他们更新后的适用于 iOS8 的 OpenGL ES Programming Guide for iOS 却提供了相反的效果:

    为获得最佳性能,您的模型应作为单个索引三角形带提交。为避免在顶点缓冲区中多次指定同一顶点的数据,使用单独的索引缓冲区并使用 glDrawElements 函数绘制三角形条

    在您的情况下,您似乎刚刚尝试了这两种方法,并发现一种方法更适合您的数据。

    【讨论】:

    • 谢谢!我想我会用绘制频率做一些测试。我还将仔细检查苹果的个人资料,看看司机是否在做任何可疑的事情。
    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多