Coding Memorandum

プログラミングに関する備忘録

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PSHUFB

仕事関係でH.264 Codecの高速化に少しばかり取り組んでました。

その作業の中の一つでバイトオーダーの変換部分がSIMD化するということで,unpackを駆使してコードを書いてみました。しかしながら,SSEレジスタ128bitの中で無駄にしている部分が多く,あまり効率的ではない・・・。

いろいろと検討する中で,SSEの新しい命令セット(SSE3より後)を見てみたところ,PSHUFBという素晴らしい命令がSSSE3で追加されているのを見つけました。バイト単位でシャッフルが可能となっています。(こんな命令が欲しかった!)
「商用コードはSSE3まで」と自主規制していますが,そろそろ先に進めても良い頃かなとも。

Intel Software Developer’s Manualによれば,次のような擬似コードの動きとなります。

▼PSHUFB : Packed Shuffle Bytes
for i = 0 to 15 {
    if (SRC[(i * 8)+7] == 1 ) then
        DEST[(i*8)+7..(i*8)+0] ← 0;
    else
        index[3..0] ← SRC[(i*8)+3 .. (i*8)+0];
        DEST[(i*8)+7..(i*8)+0] ← DEST[(index*8+7)..(index*8+0)];
    endif
}
これまでのSHUFFLE命令と異なり,マスク値の最上位ビットを1にすることで0を出力できる点も使い勝手が良さそうです。

SSSE3なのでtmmintrin.hが必要ですがVC++2005にはありません。しかし,次の宣言を書いておけばVC++2005でもIntrinsicを正しく解釈してくれました。

extern "C" {
    extern __m128i _mm_shuffle_epi8(__m128i _A, __m128i _B);
}

当初はインラインアセンブラを使うしかないかなと思っていたのですが _m128i がunion扱いなのでインラインアセンブラに直接渡せません。全面的にアセンブラ化が必要かとも思いましたが,Intrinsicsが使えたのでコンパクトにコードが書けました。


余談ですが,AMDでしか使えないSSE4aのLZCNTもよさげな感じ。符号のデコード処理向きですよね。(あまり詳しく書けませんけど)

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://msirocoder.blog35.fc2.com/tb.php/57-5da136fc
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。