Chiharu の日記

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

Parallel force - パラレル・フォース 〜スプライト管理、実装そろそろまとまるかも

結局、スプライト管理と分割描画ルーチンを 1 つのクラスとしてまとめました。1 画面分のスプライトの管理と描画をまとめてあります。描画ルーチンはスレッド用の分割単位でメソッド コールできるようにしてあります。これをスクリーン管理クラスに、単数または複数インスタンス持たせるようにします。スクリーン管理クラスは描画用のオフスクリーンを持ち、これが常に 2nd キャッシュ (できれば 1st キャッシュ) に載るよう管理し、並列描画を実行します。(字面だとわかりづらいですね。図でも描けばよいのでしょうが)
懸念事項で、コア間のキャッシュ競合の回避を考えています。通常、スプライト合成は重ね描きになるので、合成中は描画先バッファをキャッシュに載せて、合成後にキャッシュ外のメモリにノンテンポラル転送する、という工程で設計を進めていますが、更新領域あたり 1 回のノンテンポラル転送が発生するという点がちょっと引っかかっています。ノンテンポラル転送するとキャッシュはきれいなままなのですが、せっかく高クロックの CPU が FSB に引っ張られるということがあり、悩ましいと感じています。(キャッシュ競合やキャッシュ汚染するよりマシなんですけど) Intel Core i7 などはコア共通の 3rd キャッシュを数 MB オーダーで持っているため、ノンテンポラル転送しなくてもここが吸収してくれそうな気がするのですが、たとえばデュアルコアIntel Atom などは、コア共通のキャッシュがないばかりか、2nd キャッシュが 512kB (64kB at 1-way) しかないため、書き込みバッファの取り扱いに十分注意しないと、キャッシュ競合だけでなく、キャッシュ汚染がビシバシ発生しそうな気がしています。んー。
ちなみに、キャッシュキャッシュと連呼していますが、下記を満足するメモリアクセスであればキャッシュに載るという前提でコード書いています。外してたら設計し直しなんですが。

  • サイズ要件
    • 64kB 未満のメモリ領域
  • アライメント要件
    • 4kB アライメントされた先頭アドレスを持つメモリ領域
    • 4kB アライメントされた終了アドレスを持つメモリ領域
  • アクセス要件
    • 前後それぞれ 4kB へのメモリ アクセスは発生させない
    • 高頻度で連続アクセスする
    • 極力シーケンシャル アクセスする

サイズ要件は Intel Atom の 2nd キャッシュの 1-way あたりのサイズ を考慮してます。1st キャッシュを考慮した方がよいのかな。んー。アライメント要件は Intel CPU のキャッシュ制御アルゴリズムが 4kB 単位で連想判定するらしいことを考慮してます。このあたり、ちゃんと効いているかどうかを、また確認しないといけないですけど、経験上、そんなに外してない数字と要件かな、と思ってます。
動作確認まで、あとちょっと。がんばろー。