OpenGL中仅限Android的游戏:C++(NDK)与Java(Dalvik)的性能

Android only game in OpenGL: performance in C++ (NDK) vs Java (Dalvik)

本文关键字:NDK Java 性能 Dalvik Android OpenGL 游戏 C++      更新时间:2023-10-16

我知道以前有人问过类似的问题,但是......

我们希望开发(至少希望)一款独立游戏,但仍然是一款具有高质量图形的游戏,屏幕上有数百甚至数千个移动对象,因此我们期望有大量的多边形和对 hittest 的要求,也许还有一些 AI。

我知道java的基本问题是垃圾收集。但这不是问题,我们计划在游戏开始前分配所有必需的内存,对于瞬态对象,我们将使用池化(因此在游戏循环中永远不会写入 new 关键字)。我们计划使用这里提到的所有可能的技术(Google I/O 2009 - 为Android编写实时游戏)。

我们

坚持使用Java的主要原因是部署,我们只想为Android开发(至少目前是这样)。

因此,在游戏中使用Java可以实现相同的性能(即使这意味着丑陋/不是惯用的代码),就像我们用c ++一样。如果没有,具体是什么?或者,如果有可能但非常非常不切实际,这些原因是什么?

(例如,我读了一些关于java缓冲区和OpenGL不是最佳配对的内容,但不记得细节 - 也许是一些专家)

每次调用使用Java源代码中的OpenGL时,您将支付固定的额外费用。 Android 在调用周围提供了 Java 语言包装器。 例如,如果调用 glDrawArrays ,则调用 GLES20.java 中声明的本机方法,该方法在 android_opengl_GLES20.cpp 中定义。 您可以从代码中看到,它只是以最小的开销转发呼叫。

在文件中闲逛,您可以看到执行其他检查的其他调用,因此成本略高。

不可避免的成本而言,底线是使用Java源代码进行大量GLES调用的价格高于本机源代码。 (在查看带有 systrace 的 Android Breakout 的性能时,我注意到驱动程序中有很多 CPU 开销,因为我正在执行大量冗余状态更新。 从本机代码执行此操作的成本会更低,但执行零工作的成本低于执行较少工作的成本。

更深层次的问题与你是否需要以不同的方式编写代码(例如,避免分配)有关,以至于你根本无法获得相同的性能水平。 您必须使用直接ByteBuffer对象而不是简单的数组,这可能需要您进行更多的管理。 但是,除了目前计算密集型本机代码和Android上的Java代码之间的速度差异之外,我不知道有什么从根本上阻止严格Java实现的良好性能。