在我的应用程序中,我有几个简单的场景(一个80段球体,500px×1000px纹理,每分钟旋转一次),立即显示。当我打开应用程序时,一切顺利。我得到恒定的120fps,内存使用量少于50mb,CPU使用率约为30%。
然而,如果我最小化应用程序并在一分钟后回到它,或者只是停止与应用程序交互一段时间,尽管Xcode报告30fps,正常的内存使用情况,但场景都非常滞后并且大约4 fps,和超低(~3%)的CPU使用率。
我在真正的iPhone 7 iOS 10.3.1上进行测试时会出现这种情况,我不确定其他设备或模拟器上是否存在此行为。 这是我一起展示这个问题的示例项目。 (link here)我在这里做错了吗?如何让场景唤醒并恢复使用尽可能多的CPU保持良好的fps?
答案 0 :(得分:3)
我不太可能直接回答你问的问题,但可以给你一些思考点。
我在我的iPod第6代(64位),iOS 10.3.1上启动了你的演示应用程序,它从一开始就落后到FPS 2-3的大约一分钟。然后一段时间后它开始顺利旋转。去后台前景后一样。可以通过一些纹理缓存来解释它。
我调整了一个SCNView的大小,使其适合屏幕,其他视图留在后面。设置v4.showsStatistics = true
在这里我得到了什么
正如您所看到的,金属齐平对于一帧大约需要18.3毫秒,而对于一个SCNView 则仅需要大约18.3毫秒。 根据这个answer on Stackoverflow
所以,如果我的解释是正确的,那就意味着“金属 flush“测量CPU等待视频内存的时间 释放所以它可以推送更多数据并向GPU请求操作。
所以我们可能会怀疑这个问题出现在同时使用GPU的4个不同的SCNView中。
答案 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。