Mag*_*löf 7 multithreading sprite-kit
我将这个问题分为两部分。有关特定项目的多线程的另一个更具体的问题。还有一个关于多线程如何与SpriteKit紧密联系的问题。
第一个问题: 我目前正在研究一个测试项目,以了解有关SpriteKit优化的更多信息。在我的测试项目中,我有2000多个spriteNode,每个spriteNode都有一些基本的AI通过动作来移动节点。
如果将Alpha = 0设置为当前不在屏幕区域内的节点,则可以看到性能的显着提高。但是,当然,在超过2000个节点上的更新功能中执行此检查会增加负载。可能以任何方式使用多线程来承担主线程的一些负载。例如,在另一个线程上进行此检查。
一般问题: 我在SpriteKit中找不到关于多线程的太多信息,因此id希望对整个主题有更好的了解,这是我个人有的一些指导性问题。但是,如果您愿意并拥有知识,则可以随心所欲地扩展您认为重要的任何信息。
使用大型中央调度或SKAction.run(queue)。设置很容易,但是很难实现“每帧”同步到SpriteKit。在SK中将多线程用于“以后”需要的事情,例如预加载级别,检查Internet等。
考虑到SpriteKit是高级sdk,已经对其进行了非常优化。与弄乱多线程相比,您可能会发现找出优化代码的特定方法更好。
例如,平衡CPU与GPU与内存的使用...可能将任务卸载到CoreAnimation(使用GPU)进行诸如绘制形状/粒子发射器之类的工作,但是我还没有尝试过。
这是一个比我自己了解更多的人的好答案:
这也是一个很好的教程,解释了多线程以及如何使用GCD进行操作(但是SKAction可能更可取):
https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1
好的,我一直在做一些研究,现在我对SpriteKit中的多线程有了基本的了解。我决定在这里总结所有内容,以便其他对该概念一无所知的人可以开始。
基本概述。CPU核心和多线程
多线程是一种使CPU同时处理一个以上进程的方法。每个进程都有自己的线程。现在,这使我们可以执行多任务。就像同时上网和看电影一样。如果这些进程将在同一线程上运行。重新加载网页时,影片将冻结,直到重新加载完成。
线程和CPU内核是2种不同的东西。CPU核心是进行计算的硬件,而Thread更像是向CPU提供计算内容的管道。因此,从上面的示例中,将有2条管道。一种来自Web浏览器,另一种来自电影播放器,向CPU提供信息进行计算。然后,CPU将在这两个管道之间交替进行计算,从而给予它们同等的关注。这并不意味着使用两个线程可以提高CPU的性能。但是它允许两个应用程序共享CPU的资源。
多线程和SpriteKit
如果仅使用多线程,则我们可以共享CPU并同时运行多个计算。如何提高SpriteKit的性能?
好。如果您的设备仅具有1个CPU内核。我们真正能做的就是将任务划分为不同的优先级,以确保我们的主线程获得最多关注。而且,我们要给主线程以最大的关注(来自cpu)以保持FPS高,因为这是渲染周期使用的线程。因此,如果我们有一些不需要立即完成的计算,则可以在其他优先级较低的线程上运行它们。
但!如果您的设备具有2个CPU内核,就像大多数IOS设备一样。您确实可以改善游戏的性能。如前所述,渲染周期在主线程上运行。您希望该线程有足够的资源来完成其所有计算,然后再渲染下一帧。(否则您将失去帧速率)。主线程仅连接到一个内核。因此,当您以接近0 FPS的峰值达到100%CPU使用率时。您实际上只使用了设备上可用CPU资源的一半。
但是使用多线程,您可以承担一些主线程的负载,然后将其放在第二个内核上。在一个测试项目中,我设法以60 fps的速度获得150%的CPU使用率!奇怪的是有150%的CPU使用率,但实际上显示了2个内核的组合使用率。如果您有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
}
Run Code Online (Sandbox Code Playgroud)
您也可以直接在函数内部定义dispatchQueue。或代码中的任何位置。您在调度块内的所有工作将在GDC选择的适当线程上异步执行。
func myFunction(){
DispatchQueue.global(qos: .background).async {
//Do some work here...
}
}
Run Code Online (Sandbox Code Playgroud)
**** 未完待续 ***
归档时间: |
|
查看次数: |
994 次 |
最近记录: |