これらの考慮事項の何百ものバリエーションがネット全体に投稿されていることを私は知っています。しかし、私の正確な問題に対処するものは何も見つかりませんでしたので、私が光を見るのを手伝ってくれることを願っています。
私は現在、OpenGLを使用したJavaでの2Dゲーム開発をいじっています。使用されている言語とグラフィックライブラリは、より一般的な性質を持っているため、私の質問にはそれほど関係ありません。
適度に重いグラフィック(主にビットマップテクスチャ)と、場合によってはさらに重いゲームロジック(AI、衝突検出など)を持つゲームに、多かれ少なかれそのまま使用できる汎用ゲームループを設計しようとしています。
基本的に、更新(位置、速度、およびその他のゲーム関連の更新)およびレンダリング(更新された位置のテクスチャ/フレーム)できるオブジェクトのリスト/配列/バッファーを可能な限りスムーズかつ効率的に維持することを期待しています。
1)更新+レンダリング用の1つのスレッド
私は1つのスレッド(ユーザー入力を数えるときは2つ)だけを使用してシーケンシャルソリューションを試し、破棄しました。
- 変更を計算し、バッファオブジェクトを更新します
- 更新された位置のテクスチャをバックバッファにレンダリングします
- バックバッファを前面に交換します
明らかに、スワップバッファがハードウェアでブロックされている間、多くの優れたコンピューティング時間が無駄になります。これには、より効率的なソリューションが必要です。
2)更新用に1つのスレッド、レンダリング用に1つのスレッド
プログラムを更新スレッドとレンダリングスレッドに分割し、共有バッファーへのアクセスを同期することで、かなり安定したフレームレートを確保できるはずです。共有バッファへのアクセスの同期はさまざまな方法で実行できますが、すべてに共通する点が1つあります。それらはすべてスレッドの同時実行を禁止しています。これは公正なトレードオフかもしれませんが、何が同期を必要とするのか疑問に思っています。
3)2と同じですが、同期はありません
並行スレッドの不注意な実装によって引き起こされる可能性のある問題の多くを理解しています。潜在的なデッドロックを引き起こすプロデューサー/コンシューマー、リーダー/ライター、および同様の状況。ただし、次の基準が満たされている場合(および満たされている必要がある場合)に共有データの同期を確保する必要がある理由がわかりません。
- レンダリングスレッドは共有バッファからのみ読み取ることができます
- 更新スレッドは、共有バッファーからの読み取りと共有バッファーへの書き込みの両方を行うことができます(したがって、これが唯一の「ライター」です)
- ゲームの実行中、共有バッファが空になったりいっぱいになったりすることはありません
- スレッドは決してスリープしません
- レンダリングは100%正確である必要はありません。一部の共有オブジェクトがまだ更新されていないために、他のオブジェクトより1つの更新ステップ(つまり、約10〜20ミリ秒)遅れている場合は、誰も気付かないはずです。
-
だから...私がここで見逃している明らかなことは何ですか?この設定で同期が必要なのはなぜですか?
- 適切に同期されていない場合、スレッドはデータをキャッシュして問題を引き起こす可能性がありますか?
- または、不幸な時間に書き込みスレッドが中断された場合、データがどういうわけか文字化けする可能性がありますか?
- それとも、提案されたステートジーが役に立たなくなるという一般的な問題はありますか?
どんな考え、コメント、または提案も大歓迎です。または、この特定の質問がすでに他の場所で対処されている場合は、参照していただければ幸いです。