シンプルな2Dゲームエンジンを作成しています。スプライトをさまざまなスレッドで更新してレンダリングし、その方法を学びたいと思います。
更新スレッドとレンダリングスレッドを同期する必要があります。現在、2つのアトミックフラグを使用しています。ワークフローは次のようになります。
Thread 1 -------------------------- Thread 2
Update obj ------------------------ wait for swap
Create queue ---------------------- render the queue
Wait for render ------------------- notify render done
Swap render queues ---------------- notify swap done
この設定では、レンダリングスレッドのFPSを更新スレッドのFPSに制限しています。さらにsleep()
、レンダリングと更新の両方のスレッドのFPSを60に制限するために使用するので、2つの待機関数はそれほど待機しません。
問題は:
平均CPU使用率は約0.1%です。場合によっては、25%に達することがあります(クアッドコアPCの場合)。これは、待機関数がテストおよび設定関数を使用したwhileループであり、whileループがすべてのCPUリソースを使用するため、スレッドが他のスレッドを待機していることを意味します。
私の最初の質問は:2つのスレッドを同期する別の方法はありますか?私は気づいたstd::mutex::lock
、それは、whileループではないので、リソースをロックするために待っている間、CPUを使用しないでください。どのように機能しますか?std::mutex
1つのスレッドでロックし、別のスレッドでロック解除する必要があるため、使用できません。
他の質問です。プログラムは常に60 FPSで実行されるため、CPU使用率が25%に急上昇することがあるのはなぜですか。(2つのスレッドはどちらも60fpsに制限されているため、理想的には多くの同期は必要ありません)。
編集:すべての返信をありがとう。まず、レンダリングのためにフレームごとに新しいスレッドを開始しないようにしたいと思います。最初に、更新とレンダーループの両方を開始します。マルチスレッディングで時間を節約できると思います。FastAlg()とAlg()という関数があります。Alg()は私の更新objとrender objの両方であり、Fastalg()は私の「レンダーキューを「レンダラーに送信」」しています。シングルスレッドでは:
Alg() //update
FastAgl()
Alg() //render
2つのスレッド:
Alg() //update while Alg() //render last frame
FastAlg()
したがって、マルチスレッド化によって同じ時間を節約できる可能性があります。(実際にはそれが行う単純な数学アプリケーションでは、algは長いアルゴリズムであり、fastalgはより高速なアルゴリズムです)
睡眠に問題があることは一度もありませんが、睡眠は良い考えではありません。これは良くなりますか?
While(true)
{
If(timer.gettimefromlastcall() >= 1/fps)
Do_update()
}
しかし、これはすべてのCPUを使用する無限のwhileループになります。使用を制限するためにスリープ(15未満の数値)を使用できますか?このようにして、たとえば100 fpsで実行され、更新関数は1秒あたり60回だけ呼び出されます。
2つのスレッドを同期するには、createSemaphoreでwaitforsingleobjectを使用して、別のスレッドで(whileループを使用せずに)ロックおよびロック解除できるようにしますか?