« 壊れたハードディスクからデータを読む | メイン | メモリのアロケート malloc について »

2007年12月16日

動画再生エンジン開発日誌:: メモリのアライメント

    

SSE や MMX を使う時、メモリがアライメントされていないとダメなケースがあったり、アライメントされていないと遅かったりするので、メモリをアライメントする。
が、アライメントしたはずなのにうまくいかないケースに出会ったのでメモしておく。

初め、以下のようにしてアライメントさせていた。

dct_coeff = new __declspec(align(16)) short[64];

new __declspec(align(16)) でアライメントしてくれると言う確証はなかったが、このようにしてうまくいったのでそうしていた。
が、デバッガで動作させると SSE2 を使うところで落ちる。
デバッグなしで動作させると問題ない。
デバッガの有無で異なることに気付くのに時間がかかったが、それに気付いた後、上の方法ではなく自前でアライメントすることにした。
以下のような感じ。

const unsigned a = 16;
unaligned = new char[128+a-1];
dct_coeff = (short*)((unsigned)(unaligned + a - 1) & ~(a-1));

当然開放時は、unaligned を delete する。
でも、これだと2個変数を管理しないといけないので面倒くさい。
これは、確保するサイズを + sizeof(void*) とでもして、ポインタ分多く確保し、そこに元のアドレスを入れておけばいい。
つまり、以下のような感じ。
→new が返したアドレス
→アライメント後のアドレス - sizeof(void*) ここにnewが返したアドレスを入れておく。
→アライメント後のアドレス。このアドレスを返す。
当然、この時アライメント後のアドレス から new が返したアドレス を引いたサイズは sizeof(void*) より大きくないといけないので、そうなるようにアライメントする必要がある。
具体的には new が返したアドレス + sizeof(void*) のアドレスをアライメントすればいい。

後、__m128型をメンバに持つ構造体・クラス によると、Visual Studio 2005 ではアライメント関係でバグがあるようだ。
で、アライメントされたメモリの確保方法として、_aligned_malloc と _aligned_free を使う方法が書かれている。
VC ならメモリ確保にこれを使うのが楽そうだ。


関連記事・続きの記事

メモリのアライメント2
アライメントされたメモリアロケータにトラックバックされていた。 久しぶりのトラッ... [続きを読む]


投稿者 Takenori : 2007年12月16日 18:31




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