2009-02-21 5 views
22

私は商用ゲームが非常にうまくいくかどうか分かりませんが、私が出会ったオープンソースのゲームは、スレッド化に大掛かりではないようです。他のほとんどのデスクトップアプリケーションでも同様です(通常、プログラムロジックとGUIアップデートなど)。大きなプログラム(ゲームなど)で異なるスレッドの負荷が使用されるのはなぜですか?

なぜゲームにはスレッドが多数ありませんか?たとえば、物理、サウンド、グラフィックス、AIなどのスレッドを分けていますか?

+2

並列処理が難しいです。 「うわー、これはやや難しい」だけではなく、「理論的には、多くの問題が並列化できない」というものです。 –

答えて

14

最近のゲームの多くは、並列処理のための "タスク"または "ジョブ"システムを使用しています。つまり、ゲームは、複数のタスクに使用される固定数のワーカースレッドを生成します。作業は小さな断片に分割され、キューに入れられ、使用可能になったときにワーカースレッドによって処理されるように送信されます。

これは特にコンソール上で一般的になっています。 PS3はCellアーキテクチャをベースにしているため、並列処理を使用してシステムから最高のパフォーマンスを引き出す必要があります。 Xbox 360は、複数のコアを備えているため、PS3用に設計されたタスク/ジョブ設定をエミュレートできます。ほとんどのゲームでは、360、PS3、PCコードベースで多くのシステム設計が共有されているため、PCは同じ種類の戦術を使用する可能性が高いと思います。

他の回答の多くが示す通りに、スレッドセーフなコードを書くのは難しいですが、私はあなたが見ているもののために、いくつかの他の理由があると思う:

  • まず、多くのオープンソースのゲームをしています数年前特に、この世代のコンソールでは、上述のようにパラレルプログラミングが普及し、必要でさえあります。
  • 第2に、可能な限り高いパフォーマンスを得ることに懸念があるオープンソースプロジェクトはごくわずかです。 John CarmackがUtah GLXプロジェクトに指摘しているように、高度に最適化されたコードは、最適化されていないコードよりも保守が難しいことが多いため、オープンソースの文脈では後者が一般的に好まれるでしょう。
  • 第3に、ゲームで作成されたスレッドの数が少なくても、並列ジョブをうまく使用していないことを意味します。
15

主な理由は、聞こえるほどエレガントなので、3Dゲームほど複雑なプログラムで複数のスレッドを使用することは本当に本当に難しいということです。また、最近になって低コストのマルチコアシステムを導入する前に、複数のスレッドを使用してもパフォーマンスインセンティブはほとんど提供されませんでした。

23

あなたがプレイしたゲームについてはわかりませんが、ほとんどのゲームは別のスレッドでサウンドを実行します。ネットワークコード、少なくともソケットリスナは別のスレッドで実行されます。

しかし、残りのゲームエンジンは一般的には1つのスレッドで動作します。これには理由があります。たとえば、ゲーム内のほとんどの処理では、単一の一連の依存関係が実行されます。グラフィックスは、人工知能と同様に物理エンジンの状態に依存します。複数のスレッドを設計することは、並行処理のためにさまざまなサブシステム間でフレームレイテンシを持たなければならないことを意味します。これらのサブシステムが各フレームで直線的に計算されると、応答時間が短縮され、ゲームプレイがより迅速になります。並列化から最大の利益を受けるゲームの部分はもちろん、高度に並列化されたグラフィックスアクセラレータカードに負担をかけるレンダリングサブシステムです。

0

多くのスレッドを使用すると、競合状態やデータのロックには多くの問題があります。ゲームのさまざまな部分がお互いにかなり依存しているので、スレッドの負荷を使用するために必要な特別なエンジニアリングをすべて行うのはあまり意味がありません。

1

私はウィリアムと同じことを投稿しようとしていましたが、私は少しそれを拡張したいと思います。将来的に最適なコードを書くことは非常に難しいです。あなたが持っていないハードウェアにスケールするものを書くことと、あなたが持っているハードウェアで動作するものを書くことのどちらかを選択すると、ほとんどの人は後者を選択します。シングルコアのパラダイムは長い間私たちと共にいましたので、書かれているほとんどのコード(特にドアを出すプレッシャーが強いゲームの場合)は、将来の証明ではありません。

x86は、あまり寛容でないハードウェアプラットフォームの影響について考える必要がないので、プログラマーには非常に親切です。

0

スレッドを問題なく使用することは非常に難しく、ほとんどのGUI APIは、とにかくイベント駆動型のコーディングに基づいています。スレッドは、コードに遅延を加えるロック機構の使用を義務付けており、現在そのロックを保持している人に応じて遅延が予測できないことがよくあります。

私はイベントドリブンな方法ではなく、スレッドのすべての原因となる、奇妙でまたとないバグの数百人で物事を処理し、単一の(またはおそらく非常に少数の)スレッドを持つようにすることが賢明なようです。

1

複数のコアのプログラミングの技術的な課題以外にも、コマーシャルゲームは、複数のコアを搭載したローエンドシステムでは、収益をあげるためにはうまく動作しなければなりません。

今、マルチコアプロセッサがしばらく出てきたとデュアルコアはPCゲームのための最小システム要件のリストに現れる前に、主要なゲーム機は、複数のコアを持っている、それは時間の問題だということ。

は、ここで彼は、マルチスレッドを利用するために、ゲーム開発者を得ることについて話しているインテルからan interview with Orion Granatirへのリンクです。

1

ここで誰もが正しくマルチスレッド化が難しいと主張しているという事実は非常に悲しいです。私たちは必然的に並行処理システムを簡単にする必要があります。

個人的に私たちは、パラダイムシフトと新しいツールが必要になると思います。

+1

残念ながら、それはそれです。ツールはスレッドを簡単にしません(すでにopenmpやTBBなど)。問題は単純に難しいです。より良いツールを手に入れることは可能ですが、アプリを正しく動作させるためには、同時にパフォーマンスを犠牲にして表示されます。 – gbjbaanb

+0

パラダイムシフト、ツール;) – Pyrolistical

15

スレッドの実際のメリットは何ですか?単一のコアマシンでは、スレッドは実際には同時実行を許可しないということを覚えておいてください。背後では、CPUは異なるスレッド間でコンテキスト切り替えを行い、毎回少しずつ作業を行います。したがって、待ち時間のないいくつかのタスクがある場合、それらを同時に(単一のコア上で)実行することは、それらを線形に実行するよりも速くはありません。実際には、頻繁なコンテキスト切り替えのオーバーヘッドが増加するため、速度が遅くなります。

この場合、なぜ単一のコアマシンでスレッドを使用するのですか?まず第一に、タスクによっては、ディスクや他のハードウェアデバイスなどの外部リソースが利用可能になるのを待つ時間が長くかかることがあるためです。待機中のタスクでは、スレッド化によって他のタスクが続行されるため、CPUの時間をより効率的に使用できます。

第2に、タスクには、特にイベントに応答している場合に、完了するための期限があります。典型的な例は、アプリケーションのユーザーインターフェイスです。他の長時間実行されているタスクを実行中であっても、コンピュータはできるだけ早くユーザーのアクションイベントに応答する必要があります。そうしないと、ユーザーが不安定になり、アプリケーションがクラッシュした可能性があります。スレッディングはこれを可能にします。

ゲームについては、私はゲームプログラマーではありませんが、私の状況を理解するのはこれです:3Dゲームはゲーム世界のプログラマティックモデルを作成します。このゲームの世界は、前回の更新から経過した時間量に基づいて離散的なステップで更新されます。したがって、ゲームループの最後の時間から1msが経過した場合、オブジェクトの位置は速度と経過時間を使って更新されます(物理学はそれよりもはるかに複雑ですが、アイディア)。 AIや入力キーなどの他の要素も更新に寄与する可能性があります。すべてが終了すると、更新されたゲームの世界が新しいフレームとしてレンダリングされ、プロセスが再び開始されます。このプロセスは、通常、毎秒何回も実行されます。

このようにゲームループを考えると、実際にはエンジンがスレッド化の目標とほぼ同じ目標を達成していることがわかります。これには長時間実行される多くのタスク(世界の物理学の更新、ユーザ入力の処理など)があり、小さな作品に分割してインタリーブすることで同時に起こっているという印象を与えます。 CPUまたはオペレーティングシステムは、それぞれに費やされた時間を管理するために、それ自体を実行しています。これは、すべての異なるタスクを適切に同期させ、ロック、プリエンプション、リエントラントコードなどの複雑なスレッドを避けることができるということを意味します。このアプローチにはパフォーマンス上の影響はありません。実際にはシングルコアマシンはコードを直線的にしか実行できません。

マルチコアシステムを搭載していると変化します。現在、タスクは真に同時に実行することができ、一貫性のあるフレームをレンダリングするために結果を同期させることができれば、スレッドワールドを使用してさまざまなアップデートを処理するメリットが得られます。したがって、マルチコアシステムの出現により、ゲームエンジン開発者がこれに取り組むことになると考えられます。そして、それは明らかです。 Half LifeのメーカーであるValveは、最近ソースエンジンにマルチプロセッササポートを導入しました。他の多くのエンジン開発者がこれに従っていると思います。

これは、私が予想していたよりも少し時間がかかりました。私はスレッドやゲームのエキスパートではありませんが、特に目立つエラーはしないことを願っています。私が持っていると私は人々が私を修正すると確信しています:)

+2

実際、単一のコアマシンであっても、スレッドはパフォーマンスを向上させることができます。一部のマシンスイッチは、メモリストールのために実行中のスレッドをスワップします。私が正しく覚えていれば、IntelのHyperThreadingも同様のことをします。 –

+0

+1詳細な回答 –

+0

私は、スレッドを使用するときに、実際にスケジューリングを正確に監視しないことも指定します。スケジューリングアルゴリズムは、ゲーム開発者ではなく、OSによって設計されています。したがって、厳密な順序でタスクを処理する必要がある場合は、少なくとも1つのスレッドでそれを行う方が簡単です。 –

1

スレッドは死んでいます、赤ちゃん。

現実的には、ゲーム開発では、ネットワーキングやローディングのような専用のタスクをオフロードするだけではスレッドのスケーリングができません。ジョブシステムは、8つのCPUシステムがPC上でさえより一般的になっているため、唯一の方法であるように思われる。そして、インテルのLarrabeeのような今後のスーパーマルチコアシステムは、雇用システムに基づいていることをかなり保証することができます。

これはプレイステーション3とXBOX360プロジェクトではやや苦労していて、AppleもSnow Leopardの "革命的な" Grand Central Dispatchシステムを搭載しています。

スレッドにはスレッドがありますが、スレッドにすべてを入れると、すべてが速く実行されるという単純な約束は、実際には機能しません。

+0

...スレッドは、あなたが話していることの不可欠な要素です。それは抽象化の1つの追加層の真下にあります。 – colithium

関連する問題