« 炎エフェクトの高速化 全辺一気版 | メイン | 炎エフェクトプラグイン リリース2 »

2008年04月15日

吉里吉里 その他の開発日誌:: 炎エフェクトの高速化 全辺一気SSE版

    

全辺一気にやる方法をSSE化してみた。
結果、1.5% 速くなった。
うーん、大幅に変えた割には大して速くならなかった。
と言うか、そもそもテクスチャマッピングの補間部分はあまり処理時間を使っていないのかもしれないと、いくつか処理をコメントアウトして時間を計ってみた。

前にテクスチャマッピング処理自体をコメントアウトして計ったら、75% ぐらいの時間がテクスチャマッピングに使われているようだった。
今回、元データを読み込んで、書き込む部分をコメントアウトしてみたら…… 全体の 58% の時間がここで使われている。
さらに、書き込み値を固定値にして、読み込み部分をコメントアウトしたら、全体の 46% の時間がここで使われている。
つまり、データを読み込む部分に 46% の処理時間がかかっていることになる。
やっぱりテクスチャマッピングの補間部分はあんまり時間使っていないようだ。
処理時間でどこでどれだけ使われているかまとめてみると……

12% ピクセル書き込み ( テクスチャマッピング )
46% ピクセル読み込み ( テクスチャマッピン グ)
17% テクスチャマッピング残り
25% そのほかの処理 ( ブラーとかWarp Map動かしたりとか最終的な色を書き込んだりとか )

そのほかの処理はかなりいろいろやっている割に速い。
補間処理部分はそれなりか。
と言うか、ピクセル読み込み ( メモリ位置を求めたりするのも含む ) 遅い。
ここを攻めるべきだな。
今、最初に画像サイズのメモリを確保した後、縦方向の開始アドレスの配列を別に作って、2次元配列としてアクセスできるようにしている。
これを補間の段階で1次元配列としてアクセスすれば、速くなるのではないかということで試してみた。
ΔU、ΔV をまとめして処理できるようにと考えたが、これはうまくいかないようだ。
よく考えたら当然か。
そこで、x と y でアクセスしていたのを y * stride + x としてアクセスするようにした。
その際、範囲チェックは index < range として、配列の範囲ないなら値を読み出し、範囲外の時は0にすることにした。
で、動かしてみると…… 19% 程度高速化された。
速い。
後、前はしばらく動かしていたら落ちていたけど、この処理にしたら落ちなくなった。
バイリニア補間の時はまた別に関数を作らないといけないけど、この方法で行くかな。
ただ、横端の方で範囲外になると折り返されて表示されてしまうはずなので、端の方にも炎を表示する時は気を付けないと変になると思う。

Core 2 Duo E6750 ( 2.66GHz ) で 512 x 512 の範囲に描いたとして、CPU 負荷はコア1個で 14.3% 程度。
Athlon 64 X2 3800+ ( 2GHz ) で 38%程度。
Athlon XP 1600+ ( 1.4GHz ) で 71%程度。
なお、ここでの値は炎の処理のみで、この後吉里吉里の合成処理分の負荷が追加される。
で、見た目では Athlon XP 1600+ は少し遅いように感じるが、それほどではない。
何とか使えるぐらいかな。

凹ポリゴンもきちんと描画して、落ちなくなって、2の累乗値の制限もなくなって、20%程度高速化されたので、前よりもだいぶ使えるようになったはず。
後はソースコードを整理して、SSE版と非SSE版を分離して、もう少し最適化出来そうならしてみる。
その後、公開しているのを差し替えよう。
そしたら、炎は完成として、しばらくいじらないかな。



投稿者 Takenori : 2008年04月15日 23:22




comments powered by Disqus
Total : Today : Yesterday : なかのひと