2017-07-14 47 views
2

我已經分成了這個問題分爲兩個部分。有關特定項目多線程的更具體的問題。還有一個關於多線程如何與SpriteKit聯繫起來的問題。多線程在SpriteKit

第一個問題: 我目前正在開發一個測試項目,以瞭解更多關於SpriteKit優化的內容。在我的測試項目中,我有超過2000個spriteNodes,每個spriteNodes都有一些基本的AI用動作移動節點。

我可以在性能上看到一個顯著增加,如果設置alpha = 0 到目前尚未屏幕區域內的節點。但是,當然,在超過2000個節點的更新功能中執行此檢查會增加負載。 難道是可以使用多線程以任何方式把主線程的一些負載。例如,要在另一個線程上進行檢查。

一般問題: 我找不到關於SpriteKit多線程所以我還想獲得關於整個主題更好地理解,下面是我個人有一些指導方針的問題非常多的信息。但是,如果你想要,並有知識,隨意擴大這個範圍以外的任何你認爲重要的信息。

  • 什麼時候在SpriteKit中使用多線程?
  • 什麼是使用多線程的主要限制和缺陷
  • 我將如何創建一個基本的多線程示例。我可以使用swift創建代碼嗎?我在哪裏放置代碼?我開始了嗎?
  • 我應該保持什麼事記住關於多線程和渲染週期。
  • 是否有線程之間的任何差異。他們是否被「設計」用於不同的事情?
  • 你知道任何好的文章或學習資源,以瞭解更多關於多線程?
+1

我會建議在問這個https://forums.developer.apple.com/welcome問題,因爲它是一個開放式的問題,而不是真的適合SO。就性能而言,Apple建議您刪除當前屏幕上未使用的所有節點。至於隊列/多線程,請查看https://developer.apple.com/documentation/spritekit/skaction/1417799-run,也許問一個具體如何工作的問題。 – Knight0fDragon

+0

@ Knight0fDragon你能檢查我的答案,以確保我沒有任何明顯的虛假信息。 – Fluidity

+0

有一點要記住,你不應該在後臺線程上更新你的UI。如前所述,多線程對於可以等待的任務非常有用(預加載資源,從互聯網獲取圖像......)我不知道多線程如何幫助解決您的問題,因爲您正在更新每幀的.alpha屬性。聽起來不同的線程在這種情況下是無用的。 – Whirlwind

回答

2

使用大中央調度或SKAction.run(隊列)。設置起來很簡單,但對於「每幀」目的而言,很難與SpriteKit同步。多線程可以很好地在SK中用於「稍後」需要的事情,比如預加載級別,檢查Internet等。

考慮到它是高級sdk,SpriteKit已經相當優化;你可能會更好地弄清楚優化代碼的具體方法,而不是搞亂多線程。

示例,平衡CPU vs GPU vs內存使用...可能會將任務卸載到CoreAnimation(使用GPU)來繪製形狀/粒子發射器,但我沒有嘗試過。

這裏是一個很好的答案被有人知道他們在談論比我什麼了很多:

https://stackoverflow.com/a/28751747/6593818

這裏也是一個很好的教程,說明多線程和如何去做與GCD(但SKAction很可能將是首選):

https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1

+0

SKAction.run(隊列)使用GCD,除此之外,你所說的沒有什麼錯誤 – Knight0fDragon

+0

@ Knight0fDragon謝謝,我剛剛編輯過,建議它可能在窗簾後面。我現在糾正它 – Fluidity

+0

謝謝你們,這是一個很好的開始。所以隊列在:SKAction。運行(隊列)是一個dispatchQueue,必須手動設置?這個調度隊列可以是同步還是異步?我到目前爲止? –

1

好了,所以我一直在做一些研究,現在我對多個基本的瞭解閱讀SpriteKit。我決定在這裏總結一下,以便其他對這個概念瞭解甚少或根本不瞭解的人可以開始。

基本概述。 CPU核心和多線程

多線程是一種讓CPU在多個進程同時工作的方式。每個進程都有自己的線程。現在,這使我們可以執行多任務。比如同時上網和看電影。 如果這些進程將在同一個線程上運行。重新加載網頁時,電影會凍結,直到重新加載完成。

線程和CPU內核是兩個不同的東西。 CPU核心是進行計算的硬件,而線程則更像是一條向CPU提供計算事物的管道。所以從上面的例子中會有2個管道。一個來自Web瀏覽器,另一個來自向CPU提供信息進行計算的電影播放器​​。然後CPU將在這兩個管道之間交替執行兩者的計算,給予他們同樣的關注。這並不意味着使用兩個線程可以提高CPU的性能。但它允許兩個應用程序共享CPU的資源。

多線程和SpriteKit

如果多線程只能讓我們共享CPU和運行在同一時間多個計算。它如何提高SpriteKit的性能?

好吧。如果你的設備只有1個CPU核心。我們所能做的就是將任務分成不同的優先級,以確保我們的主線程得到最多的關注。而且我們想讓主線程最關注(從CPU)來保持FPS高,因爲這是我們渲染週期使用的線程。所以如果我們有一些不需要馬上完成的計算,我們可以在其他優先級較低的線程上運行它們。

但是!如果您的設備有2個CPU核心,就像大多數IOS設備一樣。你真的可以提高你的遊戲性能。如前所述,我們的渲染週期運行在我們的主線程上。你希望這個線程有足夠的資源在其渲染下一幀的時間之前完成所有的計算。 (或者你會鬆動幀率)。主線程僅連接到ONE核心。所以,當你以幾乎0 FPS的100%CPU使用率達到峯值時。您實際上只使用設備上可用的一半CPU資源。

但是對於多線程,您可以將主線程加載一些,然後將其放在第二個內核上。在一個測試項目中,我設法以60 fps獲得了150%的CPU使用率!奇怪的是有150%的CPU使用率,但它實際上顯示了2核心的組合使用。如果你有3個核心,最大值將是300%。

我知道這聽起來太好了,而且確實是這樣,正如你將在下一節中看到的那樣。

侷限性和多線程

缺點它的偉大能夠利用可從第二核心的資源。但是,有一些計算必須在主線程上運行。 如果我們看一下渲染週期。所有淡藍色區域必須在主線程上運行。評估行爲,模擬物理,約束和渲染。而這些往往是一個項目中最重的計算,並且很快就會成爲性能的瓶頸。儘管如此,根據項目結構的不同,還有很多其他的計算方法,如測量距離,更新位置,人工智能決策等,都可以放在第二個核心上,以承擔主線程的負擔。 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... 
    } 

} 

****待續***