恢复应用时SceneKit场景滞后

时间:2017-04-18 16:54:24

标签: ios performance graphics scenekit metal

在我的应用程序中,我有几个简单的场景(一个80段球体,500px×1000px纹理,每分钟旋转一次),立即显示。当我打开应用程序时,一切顺利。我得到恒定的120fps,内存使用量少于50mb,CPU使用率约为30%。

然而,如果我最小化应用程序并在一分钟后回到它,或者只是停止与应用程序交互一段时间,尽管Xcode报告30fps,正常的内存使用情况,但场景都非常滞后并且大约4 fps,和超低(~3%)的CPU使用率。

我在真正的iPhone 7 iOS 10.3.1上进行测试时会出现这种情况,我不确定其他设备或模拟器上是否存在此行为。 这是我一起展示这个问题的示例项目。 (link here)我在这里做错了吗?如何让场景唤醒并恢复使用尽可能多的CPU保持良好的fps?

2 个答案:

答案 0 :(得分:3)

我不太可能直接回答你问的问题,但可以给你一些思考点。

  1. 我在我的iPod第6代(64位),iOS 10.3.1上启动了你的演示应用程序,它从一开始就落后到FPS 2-3的大约一分钟。然后一段时间后它开始顺利旋转。去后台前景后一样。可以通过一些纹理缓存来解释它。

  2. 我调整了一个SCNView的大小,使其适合屏幕,其他视图留在后面。设置v4.showsStatistics = true 在这里我得到了什么 enter image description here

  3. 正如您所看到的,金属齐平对于一帧大约需要18.3毫秒,而对于一个SCNView 则仅需要大约18.3毫秒。 根据这个answer on Stackoverflow

      

    所以,如果我的解释是正确的,那就意味着“金属   flush“测量CPU等待视频内存的时间   释放所以它可以推送更多数据并向GPU请求操作。

    所以我们可能会怀疑这个问题出现在同时使用GPU的4个不同的SCNView中。

    1. 让我们检查一下。与第二点相比,我删除了3个SCNViews并将这些视图中的3个行星放到前面。所以一个SCNView一次有4个行星。这是截图
    2. enter image description here

      正如你所看到的那样,金属冲洗从一开始就需要5毫秒,而且一切顺利。您也可能会注意到三角形的数量(右上角图标)是我们在第一个屏幕截图中看到的数量的四倍。

      总而言之,只需尝试在一个SCNView上组合所有SCNNode,并且可能会加快速度。

答案 1 :(得分:0)

所以,我终于找到了一个部分功能的解决方案,尽管它不是我想象的那样。

我尝试的第一件事是按照Sander的回答建议将所有节点保存在单个全局场景中,并按照the second answer to this question.中的建议在其中一个SCNView上设置委托。也许这曾经起作用或者它起作用了不同的背景,但它对我不起作用。

桑德如何最终帮助我的是使用我不知道存在的性能统计数据。我为他的一个场景启用了它们,并且有关于性能的一些突出的东西: 在运行的前几秒,在应用程序获得戏剧性帧丢失之前,性能显示读取240fps。 “为什么会这样?”,我想。在具有60hz显示屏的手机上谁需要240 fps,特别是当SceneKit默认为60时。然后它命中我:60 * 4 = 240.

我猜想发生的事情是,单个场景中的每次更新都会触发“金属冲洗”,这意味着每个场景每秒刷新240次。我猜这会慢慢填充gpu缓冲区(或内存?我不知道),最终SceneKit需要开始清除它,4个视图中的240 fps对于它来说太过分了。 (这解释了为什么它在完全放弃之前最初会获得良好的性能。)

我的解决方案(这就是为什么我说“部分解决方案”),就是将每个SceneView的preferedFramesPerSecond设置为15,总共60个(我也可以在手机上使用30个,但我是不确定这是否适用于较弱的设备)。不幸的是,15fps明显波动,但比我最初的糟糕表现要好得多。

将来Apple可能会为每个SceneView启用独特的刷新功能。

TL; DR:在所有SceneView上将preferredFramesPerSecond设置为总和为60。