我把这个问题分为两部分。关于特定项目的多线程的一个更具体的问题。还有一个关于多线程如何与SpriteKit结合的问题。
第一个问题: 我目前正在开展测试项目,以了解有关SpriteKit优化的更多信息。在我的测试项目中,我有超过2000个spriteNodes,每个都有一些基本的AI通过动作移动节点。
如果设置Alpha = 0,我可以看到性能显着提高 到当前不在屏幕区域内的节点。但是,当然,在超过2000个节点的更新功能中执行此检查会增加负载。 是否有可能以任何方式使用多线程来承担主线程的负载。例如,对另一个线程进行检查。
一般问题: 我无法在SpriteKit中找到有关多线程的非常多信息,所以我希望能够更好地理解整个主题,这里有一些我个人的指导性问题。但是,如果您想要并拥有相关知识,请随意使用您认为重要的任何信息扩展到此范围之外。
答案 0 :(得分:3)
使用grand central dispatch或SKAction.run(queue)。它设置起来很容易,但很难与SpriteKit同步,每一帧都是#34;目的。多线程可以很好地在SK中用于需要的东西"稍后",如预加载级别,检查互联网等。
SpriteKit已经相当优化,因为它是一个高级sdk;你可能会更好地找出优化代码的具体方法,而不是搞乱多线程。
示例,平衡CPU与GPU与内存使用......可以将任务卸载到CoreAnimation(使用GPU),例如绘制形状/粒子发射器,但我还没有尝试过。
对于比我自己更了解他们所谈论的内容的人来说,这是一个很好的答案:
https://stackoverflow.com/a/28751747/6593818
这里也是一个很好的教程,解释了多线程以及如何使用GCD(但SKAction可能更可取):
https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1
答案 1 :(得分:3)
好的,所以我一直在做一些研究,现在我对SpriteKit中的多线程有了基本的了解。我决定在这里总结一下,所以其他对这个概念知之甚少甚至一无所知的人都可以开始了。
基本概述。 CPU核心和多线程
多线程是一种使CPU同时处理多个进程的方法。每个进程都有自己的Thread。现在这允许我们进行多任务处理。喜欢在网上冲浪和同时看电影。 如果这些进程在同一个线程上运行。重新加载网页时电影会冻结,直到重新加载完毕。
线程和CPU核心是两回事。 CPU核心是进行计算的硬件,而线程更像是一个为CPU提供计算内容的管道。所以从上面的例子中会有2个管道。一个来自Web浏览器,另一个来自电影播放器,为CPU提供信息进行计算。然后,CPU将在这两个管道之间交替执行两者的计算,从而给予它们一些相同的关注。这并不意味着使用两个线程可以提高CPU的性能。但它允许两个应用程序共享CPU的资源。
多线程和SpriteKit
如果多线程只允许我们共享CPU并同时运行多个计算。它将如何改善SpriteKit的性能?
好。如果您的设备只有1个CPU核心。我们所能做的就是将任务分成不同的优先级,以确保我们的主线程得到最多的关注。我们希望主线程最受关注(来自cpu)以保持FPS高,因为这是我们的渲染周期使用的线程。因此,如果我们有一些不需要立即完成的计算,我们可以在优先级较低的其他线程上运行它们。
BUT!如果您的设备有2个CPU内核,就像大多数IOS设备一样。你真的可以提高你的游戏性能。如前所述,我们的渲染周期在我们的主线程上运行。您希望此线程有足够的资源在渲染下一帧之前完成所有计算。 (或者你会丢帧率)。主线程仅连接到 ONE 核心。因此,当您以100%的CPU使用率达到峰值时,几乎为0 FPS。实际上,您只使用设备上可用的一半CPU资源。
但是使用多线程你可以占用一些主线程并将其放在第二个核心上。在一个测试项目中,我设法以60 fps获得150%的CPU使用率!奇怪的是拥有150%的CPU使用率,但它实际上显示了两个核心的组合使用。如果您有3个核心,则最大值为300%。
我知道这听起来好得令人难以置信,而且实际情况就是这样,正如您将在下一节中找到的那样。
多线程的限制与缺点
能够利用第二个核心提供的资源非常棒。但是,有一些计算必须在主线程上运行。 如果我们看一下渲染周期。所有淡蓝色区域都必须在主线程上运行。评估动作,模拟物理,约束和渲染。这些通常是项目中最重的计算,很快就会成为性能的瓶颈。仍然,根据项目的结构,许多其他计算,如测量距离,更新位置,AI决策等,可以放在第二个核心上,以承担主线程的一些负担。
如何在我的项目中实现多线程。
在SpriteKit中进行多线程的最简单方法是使用名为:Grand Central Dispatch(GCD)的东西。这个API开箱即用,无需在项目中包含任何内容。 GCD正在以安全有效的方式管理您的线程。
GDC入门非常简单。下面的代码将在另一个线程上运行myFunction。
run(SKAction.run(myFunction, queue: DispatchQueue.global(qos: .background)))
func myFunction(){
// Do some work here
}
您还可以直接在函数内定义dispatchQueue。或者代码中的任何地方。调度块内的所有工作都将在GDC选择的适当线程上异步执行。
func myFunction(){
DispatchQueue.global(qos: .background).async {
//Do some work here...
}
}
****将继续***