実際にベクトルの下位要素をゼロにしたいのですか?それは_mm_insert_epi32
の悪いユースケースです。インテルのCPUで2 uopsです。そのうちの1つにシャッフルポートが必要です。あなたのSSE4.1とSSE2の両方のバージョンで
、また
foo = _mm_and_si128(vec, _mm_set_epi32(-1,-1,-1, 0)); // mask off the low element
を使用し、ゼロベクトルからmovss
を使用していますが、これは2つの整数命令の間FP shuffleを使用するためのバイパス遅延が発生する可能性があります。 Cのイントリンシック版には迷惑な量のキャストがあるので、asmとして読みやすくなります。
# vec in xmm0
pxor xmm1, xmm1 ; _mm_setzero_si128()
movss xmm0, xmm1 ; zero the low 32 bits of xmm0
2倍_mm_insert_epi16
あなたは変数の内容と低要素以外の要素を交換したい場合でも、ほぼ確実にこれを行うための最善の方法ではありません。これは2-uop命令ですが、多くの場合、4 uop以下で作業を完了できます。
可変内容の場合は、_mm_cvtsi32_si128
(movd
)を使用し、2つのベクトルを一緒にシャッフルする方がよいでしょう。アンパック命令は、2つのレジスタのデータを結合するのに便利です。shufps
もあります(整数データに使用できます)。
vec
をシャッフルして、置き換える要素が下位の要素になるようにしてから、movss
(またはAND/OR)に置き換えることもできます。
おそらく2x pinsrw
は一般的なケースでは恐ろしいことではありませんが、最も具体的なケースでは、より良いものを考え出す必要があります。効率的なコードを書くための参考資料は、http://agner.org/optimize/とx86タグwikiを参照してください。