2012-01-22 3 views
0

私はいくつかのマルチスレッドビデオゲームのコードを作っています。コーディングを始める前に、マルチスレッドのゲームデザインに対する漠然としたValveの解決策を説明する記事を見ました。記事から集めた重要な概念は、スレッドの同期です。これがValveの仕組みであるかどうかは分かりませんが、それぞれがゲームループを実行する複数のスレッドを想像しています。各反復の終わりに、スレッドは一時停止し、他のスレッドが現在の反復を完了するのを待ってから、共有データを同期させます。私はオーバーヘッドの他に、この管理スキームがあると考えています。スレッドが完全に非同期で動作するようにするだけでは違いはありません。記事では、同期のために排他的に使用されるスレッドが記載されていましたが、正しく動作するには別のソリューションを取得しようとしています。これは私が(試す)それを行う方法です:ループスレッドの同期

 // at end of loop on each thread... 
     sig_thread_done(); 

     while (!is_sync_done()) 
     { 
      PauseExecution(1); 
     } 

sig_thread_doneとis_sync_doneはすべて「スレッド」のリストを制御し、別のクラスからの関数オブジェクトです。これらの機能は、次のようになります。

bool Core::IsFrameDone() 
{ 
    MutexLock lock(manager_mutex); 

    if (waiting_components == -1) 
    { 
     waiting_components = 0; 
     return true; 
    } 
    return false; 
} 

void Core::SignalFrameDone() 
{ 
    MutexLock lock(manager_mutex); 

    if (++waiting_components == (int)components.size()) // components == threads 
    { 
     //sync shared data... 
     waiting_components = -1; // -1 signifies that all threads have completed their iteration 
    } 
} 

問題は速いスレッドは待機ループを抜けると、他のスレッドがあります終了する機会を持って前に再びそれを周りに戻って来ることができるということです。そのため、他のスレッドは、別のスレッドが待機を開始してシステム全体が永久に待機してしまう前に、is_sync_doneがfalseを返して終了することを逃します。

この問題を簡単に解決する方法が見つかりません。いくつかの独立したスレッドが同期を実行している間、同期は停止しないので、私はこのアプローチが本当に好きです。

私は、誰かが提供しなければならない洞察力や提案を感謝します。

Link to article.

+0

あなたが参照している記事にリンクすることをお勧めします。 –

+1

概念的には、バリアを実装しようとします。代わりに、代わりにテスト済みの実装を使用してみましょう。 'pthread_barrier'? –

+0

@AlexeyKukanovありがとうございます。私はそれを調べます。 – Jim

答えて

0

私はあなたがThread barrierを再発明しようとしていると思います。

+0

それは誰もが言っているようだ。私は以前にスレッドの壁を聞いたことがない、私はこのプロジェクトを始める前にもっと読んでおくべきだったと思う。コメントありがとう。 – Jim

0

Win32イベント(またはその配列)のようなものをバリアに同期したい場合は、これで説明したような状況にならないことが保証されます(障壁によってすべてが同じフレーム)、同時にCPU時間を解放します。イベントの待機はカーネル信号として実行され、その信号が受信されるまでスレッドをスリープします。また、待ち時間のないアルゴリズムを使用する場合は、ジョブ/タスクベースのスレッドモデルを使用している場合は特に効果的です。特定のものをシステムから切り離すことができます。

hereは、ソースエンジンのマルチスレッド化、より深く、技術的な点で優れた出版物です(この種のミューテックスを避けることも具体的に述べています)。

+0

ありがとうございます。私はこれを試す前に、すべてのスレッドを非同期で実行し、必要に応じてmutexを使用しました。これにより、散発的な同期のオーバーヘッドがなくなります。 – Jim