2010-04-07 80 views
0

比方說,我有一個域模型,即時嘗試與多線程兼容。 原型域是由Space,SpaceObject和Location對象組成的遊戲域。 SpaceObject有Move方法和Asteroid並且Ship擴展這個對象具有對象的特定屬性(Ship有一個名稱並且Asteroid有一個顏色)C#多線程域設計

比方說,我想讓每個對象的Move方法運行在單獨的線程。這將是愚蠢的,因爲有10000個對象,我會有10000個線程。核心/線程之間分離工作負載的最佳方式是什麼?

我正在嘗試學習併發的基礎知識,並構建一個小型遊戲來構建很多概念的原型。

我已經做了什麼,是建立一個域,並帶有定時器的線程模型,該定時器根據間隔啓動事件。如果發生事件,我想用任何SpaceObject的新位置更新我的整個模型。 但是我不知道在事件發生時如何以及何時用工作負載啓動新線程。

有些工作人員告訴我,你無法更新你的核心域多線程,因爲你必須同步一切。但在這種情況下,我無法在雙核四核服務器上運行我的遊戲,因爲它只會使用1個CPU來完成最困難的任務。

任何人都知道該怎麼辦?

規格的反應Deltreme:

你是正確的是絕對,你的方法在大多數情況下工作。但是, 線程必須更新Space類中的spaceobject的位置。

比方說,我有兩個SpaceObjects旁邊的彼此,他們正在走向彼此。 1對象位於線程A中,另一個位於線程B中。 一旦我更新對象,線程必須一起寫入空間,以在Tile(空間的單獨部分)中寫入新值。那個人通話不能在不同的線程同時進行,造成空間物體就會爆發......

什麼都可能發生的碰撞,我可以寫,如果他們有2艘@ 1瓦時發生的事件。這不是問題。

我在考慮10000艘船的情況下,CPU主要是在線程之間切換,而不是全部運行它們。因此,爲了提高性能,我希望能夠同時「一切」

回答

1

您可以使用System.Threading.ThreadPool或即將推出的任務並行庫根據可用內核數量自動管理您的線程數。

併發問題的一種可能的方法是隻鎖定您當前的SpaceObject可以與之交互的其他SpaceObjects。這將在大多數情況下提供足夠的性能,但在最糟糕的情況下,處理大型交互將由單個線程完成。你最終需要鎖定多少取決於你的模擬參數。如果對象在定時器的單個滴答內不能完全通過對方,那麼只需檢查重疊對象即可離開。對於快速移動的物體,您需要檢測相交的運動矢量。

+0

謝謝,這很有幫助,這意味着我可以在最壞的情況下優化0%,在最好的情況下可以優化0%。你知道有什麼方法可以提高這些賠率嗎? – 2010-04-07 10:03:06

0

我假設您創建快照:在情況下每個SpaceObject位於某個位置,並且在每個SpaceObject移動到另一個位置之後,您將看到情況B.

對於10000個對象,情境A和B之間的轉換爲10000個移動呼叫。 Move()聽起來像一個相當快的方法,即。使用當前的位置和方向創建新的位置。

在這種情況下,您可以創建10個線程(或使用線程池),並指定說50個SpaceObjects到它,因爲它會再計算出新的位置。如果一個線程完成了,並且仍有SpaceObjects需要移動,則可以爲該線程分配另一個50。

+0

查看我更新的問題 – 2010-04-07 09:31:38

0

正如Hirvox所說,ThreadPool是一個不錯的選擇。我會避免用每個SpaceObject的線程來思考,而是把它想象成一個SpaceObjects的大隊列,它們都需要在一個時間間隔上更新它們的位置,然後使用線程來執行移動計算。對象;這非常適合ThreadPool。它可能不是一個實際的隊列,但可以是一個有序的字典,但你明白了。

當您完成移動計算後,使用類似的方法處理任何碰撞。處理快速移動者的一種方法是在非常短的時間間隔內工作,每隔一段時間更新快速移動者,每隔一段時間更新一次中等移動者,每隔十分鐘更新一次慢速移動者。

只是爲了好玩,請考慮使用視頻卡進行計算 - 高端圖形處理器針對同步計算的空白進行了優化。