最適化ー

IDCT以外はFFmpegとIPPの関数の対応がわかんない。無理だー。

なんとなくunsigned char bytes[64]同士の飽和加算の最適化をしてる最中。
MMXみたいに32bitレジスタで4バイトを並列処理しようとしてるんだけど、なかなか難しい。

  • -

アルゴリズム自体は完成して、単体テストではまったく問題無い。
のだが、mplayerに組み込んだ途端、謎の挙動を示しだす……。


unsigned char hoge[4];
hoge[0] = 0x78, hoge[1] = 0x56, hoge[2] = 0x34, hoge[3] = 0x12;


@ uint32_t foobar(unsigned char *hoge)
.global foobar
foobar:
stmFD sp!, {r4-r11, r14}
ldr r0, [r0]
ldmFD sp!, {r4-r11, r15}

てな単純な命令でも、返り値が化ける。


printf("%08x\n", hoge[0] | (hoge[1]<<8) | (hoge[2]<<16) | (hoge[3]<<24));
>>> 0x12345678
printf("%08x\n", *( (uint32_t *)buf) );
>>> 0x00560078

この結果も1行目と2行目で違うんだけど、なぜだろう?
ちなみに、上記アセンブリコードの結果はprintfの2行目の結果と一致する。

アラインメントが整っていないわけじゃないし……。なんか根本的な間違いを犯している?

  • -

typedef short DCTELEM !? ぐはっ、byteと勘違いしてた!

saturation(signed short + unsigned char)をしないといかんのか。

また最初から考えなおさないと……。

現状ではバイト単位のロード/ストア(ldrb/strb)とルックアップテーブル(無駄なメモリアクセス)で計算しているんで、かなり遅いはず。適当にプロファイルを取ったら、全体の10%の時間を消費してる。これをなんとか分岐無しのワード単位並列演算に……。飽和減算と飽和加算を同時に行うのは無理か?

こういう最適化って最近のGHz級CPUだとあまり意味がなくて(やらなくても十分な速度で動作するから可読性を優先する)、最適化にまつわる話もあまり見なくなってきた。Pentium1のU,Vパイプのペアリングがどうとか言っていた時代が懐かしい(笑)