« 壊れたハードディスクからデータを読む | メイン | メモリのアロケート malloc について »
2007年12月16日
動画再生エンジン開発日誌:: メモリのアライメント
Tweet @jin1016をフォロー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