multithreading - SpriteKit中的多线程

标签 multithreading sprite-kit

我将这个问题分为两部分。有关特定项目的多线程问题,还有一个更具体的问题。还有一个关于多线程如何与SpriteKit紧密联系的问题。

第一个问题:
我目前正在做一个测试项目,以了解有关SpriteKit优化的更多信息。在我的测试项目中,我有2000多个spriteNode,每个spriteNode都有一些基本的AI通过 Action 来移动节点。

如果将Alpha设置为0,则可以看到性能显着提高
到当前不在屏幕区域内的节点。但是,当然,在超过2000个节点上的更新功能中执行此检查会增加负载。
是否有可能以任何方式使用多线程来承担主线程的某些负载。例如,在另一个线程上进行此检查。

常见问题:
我在SpriteKit中找不到太多有关多线程的信息,因此id希望对整个主题有更好的了解,这是我个人有的一些指导性问题。但是,如果您愿意并拥有知识,则可以使用您认为重要的任何信息随意扩展到此范围之外。

  • 什么时候在SpriteKit中使用多线程会有意义?
  • 使用多线程
  • 有哪些主要限制和陷阱?
  • 我将如何创建一个基本的多线程示例。我可以使用swift创建代码吗?我在哪里放置代码?我应该开始吗?
  • 关于多线程和渲染周期,我应该牢记什么。
  • 线程之间是否有任何区别。它们是“设计”用于不同事物的吗?
  • 您知道任何好的文章或学习资源来了解有关多线程的更多信息吗?
  • 最佳答案

    好的,我一直在做一些研究,现在我对SpriteKit中的多线程有了基本的了解。我决定在这里总结所有内容,以便对这个概念了解甚少或一无所知的其他人可以上手。

    基本概述。 CPU内核和多线程

    多线程是一种使CPU同时处理一个以上进程的方法。每个进程都有自己的线程。现在,这使我们可以执行多任务。就像在网上冲浪和同时看电影一样。
    如果这些进程将在同一线程上运行。重新加载网页时,影片将卡住,直到重新加载完成。

    线程和CPU内核是2种不同的东西。 CPU核心是进行计算的硬件,而线程更像是向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%。

    我知道这听起来太好了,难以置信,实际上,确实如此,正如您将在下一节中找到的那样。

    多线程的局限性和缺点

    能够利用第二个核心的可用资源真是太好了。但是,有些计算必须在主线程上运行。
    如果我们看一下渲染周期。所有浅蓝色区域必须在主线程上运行。评估 Action ,模拟物理场,约束并渲染。这些通常是项目中最繁重的计算,很快它就成为性能的瓶颈。但是,根据项目的结构,可以在第二个内核上进行许多其他计算,例如测量距离,更新位置,AI决策等,以承担一些主线程的负担。 enter image description here

    如何在我的项目中实现多线程。

    在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...
        }
    
    }
    

    **** 待续 ***

    关于multithreading - SpriteKit中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45106332/

    相关文章:

    java - 如何从非 Activity 线程调用 Activity ?

    .net - .NET多线程和单元测试

    multithreading - 如何使用 g++ 在 64 位 Solaris sparc 上编译线程本地存储 (TLS)

    ios - 尝试使用 SpriteKit 场景 (SWIFT) 在 didMoveToView 中使用 waitForDuration 来延迟生成节点,但不起作用

    objective-c - 如何从 SKShapeNode 裁剪出 SKLabelNode?

    java - Camel 路线执行优先级

    Java 实例变量同步

    ios - XCode 升级后出错,ios 8.1,spritekit 和 swift,对象构建 'NSData(contentsOfFile:options:error:)'

    ios - Spritekit 运动轨迹

    ios - 开始触摸的计数不等于完成触摸的计数