STATUS: 故障中
「赤く塗れ」を改良中。
画面の赤い部分を徐々に暗くする処理を高速化しようと思い、再内周ループを最適化してます。
for ( int x=0; x<m_dibsec.m_nWidth; x++ ) {
いま、こんな感じで、ループの条件判断の度にメンバ変数を見に行くので、これは無駄すぎ。
このコードでは1000回ループで、400msくらいかかっています。
ということで次のように変えてみました。
int nWidth = m_dibsec.m_nWidth;
for ( int x=0; x<nWidth; x++ ) {
一度ローカル変数に代入するようにしてみました。
が、これでベンチをとると1000回ループで、500msくらいかかるようになってしまいまいた。逆に遅くなってるよ。
リスティングファイルのASMコードをみると、このループ自体はループ変数がレジスタに割り当てられて高速化しているのですが、ループ内部の処理でレジスタが足りなくなってメモリアクセスを行うようになってしまったようです。
x86はレジスタ少なすぎ。
とか文句をいっていてもしょうがないので、もうちょっと改良したら1000回ループで350msくらいで終わるようになりました。
もともと突込みどころが沢山あるコードだったぽい。
「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」
そこは! (スコア:1)
浮動小数レジスタですが、カウントにも一応使えます。
MMXと違ってフラグを変える命令 (comiss [nifty.com]) があるので分岐できます。
と言ってみましたが、最近触ってないので自信ないです(ぉ
Re:そこは! (スコア:1)
でも、直接アセンブラで書いてしまったほうが最適化であれこれ悩むより楽かもしれないかな。
でもそもそも今のプログラム、SSEが載っているほうなCPUでは処理速度ぜんぜん問題ないので最適化はどうでもよくて、むしろSSEが載っていないCPUでの高速化をどうにかしたいところです。
MMX非搭載CPUはいまさら考えなくてもいいのか悩みどころです。MMXの拡張命令使えば並列で処理できるのはもちろんですが、飽和演算が使えるので条件分岐がなくなってかなり速くなりそうではあります。