私が見つけた SSE シフト命令は、すべての要素で同じ量だけシフトできます。
_mm_sll_epi32()
_mm_slli_epi32()
異なる要素に異なるシフトを適用する方法はありますか? このようなもの:
__m128i a, __m128i b;
r0:= a0 << b0;
r1:= a1 << b1;
r2:= a2 << b2;
r3:= a3 << b3;
私が見つけた SSE シフト命令は、すべての要素で同じ量だけシフトできます。
_mm_sll_epi32()
_mm_slli_epi32()
異なる要素に異なるシフトを適用する方法はありますか? このようなもの:
__m128i a, __m128i b;
r0:= a0 << b0;
r1:= a1 << b1;
r2:= a2 << b2;
r3:= a3 << b3;
_mm_shl_epi32()
まさにそれを行う組み込み関数が存在します。
http://msdn.microsoft.com/en-us/library/gg445138.aspx
ただし、XOP 命令セットが必要です。AMD Bulldozer および Interlagos プロセッサ以降にのみ、この命令があります。Intel プロセッサでは使用できません。
XOP 命令なしで実行したい場合は、難しい方法で実行する必要があります。それらを引き出して、1 つずつ実行します。
XOP 命令がなくても、次の組み込み関数を使用して SSE4.1 でこれを行うことができます。
_mm_insert_epi32()
_mm_extract_epi32()
これらにより、128ビットレジスタの一部を通常のレジスタに抽出して、シフトを実行して元に戻すことができます.
後者の方法を使用すると、恐ろしく非効率になります。_mm_shl_epi32()
それがそもそも存在する理由です。
XOP がなければ、選択肢は限られます。シフト カウント引数の形式を制御できる場合は_mm_mullo_pi16
、2 の累乗で乗算することはその累乗でシフトすることと同じであるため、使用できます。
たとえば、SSE レジスタ内の 8 つの 16 ビット要素を でシフトしたい場合は<0, 1, 2, 3, 4, 5, 6, 7>
、シフト カウントで累乗した 2 を掛けることができます<0, 2, 4, 8, 16, 32, 64, 128>
。
状況によっては、これは次の代わりになり_mm_shl_epi32(a, b)
ます:
_mm_mullo_ps(a, 1 << b);
一般的に言えば、これには一定の値が必要です。古い SSE 命令を使用しb
て効率的に計算する方法がわかりません。(1 << b)