【问题标题】:Android: 60 fps in Debug mode but slow down in Release modeAndroid:在调试模式下为 60 fps,但在发布模式下速度变慢
【发布时间】:2016-09-09 17:00:29
【问题描述】:

我为 Android 编写了一个游戏(使用 Android Studio、Gradle、带有 OpenGL ES 2.0 且没有 NDK 的 Java 框架,游戏是 3D)我在调试模式下达到了大约 60fps 的速度。 当我构建发布版本时,帧速率急剧下降。 我试过了:

-在没有优化和混淆的版本中构建。 -我测试了不同的优化(尤其是内联代码) -我尝试了许多不同的设备,但都或多或少地感觉到帧速率下降。

发布版本比仅在资产加载时间上进行调试更快。 我认为编译只支持小代码大小,而不是代码速度(众所周知,它会消耗更多内存并增加代码大小,Gradle 似乎没有处理 Java 编译器的问题)。

有没有人知道这种情况的任何具体原因。努力达到适当的速度,然后因为一些工具愚蠢的问题而失去它,真是令人沮丧。

-更新

帧速率几乎恒定,但低于 30 fps(在同一设备上)。 我觉得莫名其妙的是,在调试模式下,即使有所有活动日志,游戏也非常流畅和清晰。 这是我的第一个 Android 游戏,但我在其他平台的图形编程和图形引擎方面有 20 年的经验。 我认为可能是某些Android服务的干扰限制了游戏的速度以节省能源。 我不为游戏的主循环使用外部库,循环期间没有内存负载(内存在调试中是恒定的)。 我在调试 Android 的发布版本方面没有太多经验(会更仔细地看,但我怀疑这是我的代码的错)。 无论如何感谢您的回答。

-更新2

使用 Android Studio 的 CPU 跟踪器,发布版本的帧似乎比 Debug 版本的帧快,这是应该的。 对我来说,减速的原因是我的代码(现在)。 这件事没人发生吗?

-更新3

链接到 systrace(仅适用于 Chrome 浏览器):

Release systrace

Debug systrace

-更新 4

我在编译时注意到了这一点:

发布 执行任务:[:app:assembleRelease]

按需配置是一项孵化功能。 增量java编译是一个孵化特性。 :app:preBuild UP-TO-DATE :app:preReleaseBuild UP-TO-DATE :app:checkReleaseManifest :app:pre调试构建最新版本


调试 执行任务:[:app:incrementalDebugSupportDex]

按需配置是一项孵化功能。 增量java编译是一个孵化特性。 :app:buildInfoDebugLoader :app:preBuild UP-TO-DATE :app:preDebugBuild UP-TO-DATE :app:checkDebugManifest :app:pre发布Build UP-TO-DATE

有没有办法编辑 Gradle 的任务?

【问题讨论】:

  • 您确定是工具有问题吗?无论如何,我只有一个建议:分析您的应用程序并找出问题所在。仅从您问题中的信息来看,我怀疑有人可以帮助您。
  • 也许你有一些并发问题(比如,一些代码在发布模式下变得更快,并且执行更频繁地阻塞了一些其他代码,这会影响 fps)。请定义“帧率急剧下降”。请尝试制作最少的示例或在您的代码中找到性能瓶颈并发布它。
  • 一般来说,某个版本总是会快得多,因为不包括所有与调试相关的代码。
  • 是的,@Anton 所说的正是我的怀疑。分析是弄清楚发生了什么的唯一方法。
  • 渲染过程中触摸屏幕会提高帧率吗?

标签: android opengl-es-2.0 compiler-optimization frame-rate


【解决方案1】:

这是部分解决方案。

我刚刚用内联函数替换了一个调用另一个函数的函数:

原创

public void ParentChildrenMatrix(final D3GMATRIX ResultMatrix, final D3GModel3D Model)
{

    D3GModel3D P = Model;


    ResultMatrix.copy(Model.WorldMatrix);

    while(P.Parent != null)
    {

        D3GMATRIX.multiplyMM(Hierarchy, P.Parent.WorldMatrix, ResultMatrix);

        ResultMatrix.copy(Hierarchy);

        P = P.Parent;
    }

}

替代程序

public void ParentChildrenMatrix(final D3GMATRIX ResultMatrix, final D3GModel3D Model)
{

    D3GModel3D P = Model;


    ResultMatrix.copy(Model.WorldMatrix);

    while(P.Parent != null)
    {

        Hierarchy.M[_11] = (ResultMatrix.M[_11] * P.Parent.WorldMatrix.M[_11]) + (ResultMatrix.M[_12] * P.Parent.WorldMatrix.M[_21]) + (ResultMatrix.M[_13] * P.Parent.WorldMatrix.M[_31]) + (ResultMatrix.M[_14] * P.Parent.WorldMatrix.M[_41]);
        Hierarchy.M[_12] = (ResultMatrix.M[_11] * P.Parent.WorldMatrix.M[_12]) + (ResultMatrix.M[_12] * P.Parent.WorldMatrix.M[_22]) + (ResultMatrix.M[_13] * P.Parent.WorldMatrix.M[_32]) + (ResultMatrix.M[_14] * P.Parent.WorldMatrix.M[_42]);
        Hierarchy.M[_13] = (ResultMatrix.M[_11] * P.Parent.WorldMatrix.M[_13]) + (ResultMatrix.M[_12] * P.Parent.WorldMatrix.M[_23]) + (ResultMatrix.M[_13] * P.Parent.WorldMatrix.M[_33]) + (ResultMatrix.M[_14] * P.Parent.WorldMatrix.M[_43]);
        Hierarchy.M[_14] = (ResultMatrix.M[_11] * P.Parent.WorldMatrix.M[_14]) + (ResultMatrix.M[_12] * P.Parent.WorldMatrix.M[_24]) + (ResultMatrix.M[_13] * P.Parent.WorldMatrix.M[_34]) + (ResultMatrix.M[_14] * P.Parent.WorldMatrix.M[_44]);

        Hierarchy.M[_21] = (ResultMatrix.M[_21] * P.Parent.WorldMatrix.M[_11]) + (ResultMatrix.M[_22] * P.Parent.WorldMatrix.M[_21]) + (ResultMatrix.M[_23] * P.Parent.WorldMatrix.M[_31]) + (ResultMatrix.M[_24] * P.Parent.WorldMatrix.M[_41]);
        Hierarchy.M[_22] = (ResultMatrix.M[_21] * P.Parent.WorldMatrix.M[_12]) + (ResultMatrix.M[_22] * P.Parent.WorldMatrix.M[_22]) + (ResultMatrix.M[_23] * P.Parent.WorldMatrix.M[_32]) + (ResultMatrix.M[_24] * P.Parent.WorldMatrix.M[_42]);
        Hierarchy.M[_23] = (ResultMatrix.M[_21] * P.Parent.WorldMatrix.M[_13]) + (ResultMatrix.M[_22] * P.Parent.WorldMatrix.M[_23]) + (ResultMatrix.M[_23] * P.Parent.WorldMatrix.M[_33]) + (ResultMatrix.M[_24] * P.Parent.WorldMatrix.M[_43]);
        Hierarchy.M[_24] = (ResultMatrix.M[_21] * P.Parent.WorldMatrix.M[_14]) + (ResultMatrix.M[_22] * P.Parent.WorldMatrix.M[_24]) + (ResultMatrix.M[_23] * P.Parent.WorldMatrix.M[_34]) + (ResultMatrix.M[_24] * P.Parent.WorldMatrix.M[_44]);

        Hierarchy.M[_31] = (ResultMatrix.M[_31] * P.Parent.WorldMatrix.M[_11]) + (ResultMatrix.M[_32] * P.Parent.WorldMatrix.M[_21]) + (ResultMatrix.M[_33] * P.Parent.WorldMatrix.M[_31]) + (ResultMatrix.M[_34] * P.Parent.WorldMatrix.M[_41]);
        Hierarchy.M[_32] = (ResultMatrix.M[_31] * P.Parent.WorldMatrix.M[_12]) + (ResultMatrix.M[_32] * P.Parent.WorldMatrix.M[_22]) + (ResultMatrix.M[_33] * P.Parent.WorldMatrix.M[_32]) + (ResultMatrix.M[_34] * P.Parent.WorldMatrix.M[_42]);
        Hierarchy.M[_33] = (ResultMatrix.M[_31] * P.Parent.WorldMatrix.M[_13]) + (ResultMatrix.M[_32] * P.Parent.WorldMatrix.M[_23]) + (ResultMatrix.M[_33] * P.Parent.WorldMatrix.M[_33]) + (ResultMatrix.M[_34] * P.Parent.WorldMatrix.M[_43]);
        Hierarchy.M[_34] = (ResultMatrix.M[_31] * P.Parent.WorldMatrix.M[_14]) + (ResultMatrix.M[_32] * P.Parent.WorldMatrix.M[_24]) + (ResultMatrix.M[_33] * P.Parent.WorldMatrix.M[_34]) + (ResultMatrix.M[_34] * P.Parent.WorldMatrix.M[_44]);

        Hierarchy.M[_41] = (ResultMatrix.M[_41] * P.Parent.WorldMatrix.M[_11]) + (ResultMatrix.M[_42] * P.Parent.WorldMatrix.M[_21]) + (ResultMatrix.M[_43] * P.Parent.WorldMatrix.M[_31]) + (ResultMatrix.M[_44] * P.Parent.WorldMatrix.M[_41]);
        Hierarchy.M[_42] = (ResultMatrix.M[_41] * P.Parent.WorldMatrix.M[_12]) + (ResultMatrix.M[_42] * P.Parent.WorldMatrix.M[_22]) + (ResultMatrix.M[_43] * P.Parent.WorldMatrix.M[_32]) + (ResultMatrix.M[_44] * P.Parent.WorldMatrix.M[_42]);
        Hierarchy.M[_43] = (ResultMatrix.M[_41] * P.Parent.WorldMatrix.M[_13]) + (ResultMatrix.M[_42] * P.Parent.WorldMatrix.M[_23]) + (ResultMatrix.M[_43] * P.Parent.WorldMatrix.M[_33]) + (ResultMatrix.M[_44] * P.Parent.WorldMatrix.M[_43]);
        Hierarchy.M[_44] = (ResultMatrix.M[_41] * P.Parent.WorldMatrix.M[_14]) + (ResultMatrix.M[_42] * P.Parent.WorldMatrix.M[_24]) + (ResultMatrix.M[_43] * P.Parent.WorldMatrix.M[_34]) + (ResultMatrix.M[_44] * P.Parent.WorldMatrix.M[_44]);

        System.arraycopy(Hierarchy.M, 0, ResultMatrix.M, 0, 16);



       P = P.Parent;
    }

}

但是我不明白为什么调试版本中的原始功能比旧版本中的运行速度要快得多。 唯一有效的原因是在发布时函数被错误地“优化”(最好不要优化)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多