Chiharu の日記

絵描き C/C++ プログラマーの日記です。

Parallel force - パラレル・フォース 〜スプライト管理、まずはパイプライン 1 段

とりあえず合成先スクリーン 1 枚の描画ルーチンが完成。表画面への転送も含めて、動作確認が取れるところまできました。

スクリーンサイズは 800x600 pix (BGRX)、50 枚のスプライトをαブレンディングしてみました。Intel Core 2 Duo (1.86 GHz) でスレッド数振って 1 フレームあたりの描画時間 (表画面への転送込み) を計測したら下記のような感じになりました。(絶対値はともかく、相対値に注目です)

  • 1 スレッド: 113ms
  • 2 スレッド: 58ms

うん。結構コア数比例で伸びる感じですね。良好良好。ただこれ 1 点注意があります。表画面への転送には StretchDIBits API を使用しているのですが、これをスレッド間で同時にコールすると失敗することがあり、この API 呼び出しだけはクリティカルセクションでガードしてシーケンシャルに実施してます。なので、合成負荷よりも表画面への転送負荷が大きい場合は、コア数比例というほどにはスコアが伸びないと思います。DirectX 使ってサーフェイスに直接描画しろよ、という話もありますが、DirectX を使うと、とたんに周辺コードが増えるので極力使いたくないなぁ、とか思ってます。サーフェイスのフォーマット対応やロストしたサーフェイスのリストア処理なんて面倒くさすぎて失神しそうです。
また、今回の実装では、スレッドをコアに貼り付けるようなことはしていません。その代わり、合成バッファをスレッドに貼り付けるようにしてます。スレッド割り当ての最適化は OS に任せて、データ割り当てだけプログラムで制御してるって状況です。まぁ、割り当ての有無の相違を検証していないので、どれくらい効果があるのかわかりませんけどね。せっかく合成バッファでキャッシュ サイズを考慮しているので、載るならコア別でキャッシュに載るといいかな、とか。そんなことを期待してます。
とりあえずネイティブな合成処理はできました。次は多段スクリーンかもうちょっと上位のエフェクト系機能に取り掛かろうかな。今は SIMD を使っていないので、気持ちが乗ったらそちらにも手を出そうかと思いますが、優先順位は低いかな。まずは機能を作っていこうと思います。