hirschhornsalzのソリューションの変更として、iがコンパイル時定数の場合、シャッフルを使用してユニオンパスを完全に回避できます。
template<unsigned i>
float vectorGetByIndex( __m128 V)
{
    // shuffle V so that the element that you want is moved to the least-
    // significant element of the vector (V[0])
    V = _mm_shuffle_ps(V, V, _MM_SHUFFLE(i, i, i, i));
    // return the value in V[0]
    return _mm_cvtss_f32(V);
}
スカラーフロートはXMMレジスタの下部要素であり、上部要素はゼロ以外にすることができます。_mm_cvtss_f32無料で、ゼロ命令にコンパイルされます。これは、単なるshufpsとしてインライン化されます(またはi == 0の場合は何もありません)。
コンパイラーは、シャッフルを最適化するのに十分なほど賢いi==0ので(長く廃止されたICC13を除く)、。は必要ありませんif (i)。  https://godbolt.org/z/K154Pe。clangのシャッフルオプティマイザは、コンパイルvectorGetByIndex<2>しmovhlps xmm0, xmm0て1バイト短くなりshufps、同じ下位要素を生成します。はコンパイル時定数であるため、他のコンパイラではswitch/を使用して手動でこれを行うことができますが、手動でベクトル化するときにこれを使用するいくつかの場所での1バイトのコードサイズは非常に簡単です。casei
_mm_extract_epi32(V, i);ここでは、SSE4.1は有用なシャッフルではないことに注意してください。FPextractps r/m32, xmm, immビットパターンを整数レジスタまたはメモリにのみ抽出できます(https://www.felixcloutier.com/x86/extractps)。(そして、組み込み関数はそれをとして返すintので、C ++コードで型のパンニングを行わない限り、実際にはextractps+にコンパイルさcvtsi2ssれてFPビットパターンでint-> float変換を実行します。ただし、コンパイルされると予想されます。 to extractps eax, xmm0, i/movd xmm0, eaxこれはshufpsに対してひどいです。)
有用な唯一のケースextractpsは、コンパイラがこの結果を直接メモリに格納し、その格納を抽出命令に折りたたむ場合です。(i!= 0の場合、それ以外の場合はを使用しますmovss)。結果をスカラーフロートとしてXMMレジスタに残すのshufpsは良いことです。
(SSE4.1insertpsは使用可能ですが、不要です。任意のソース要素を取得しながら、他の要素をゼロにすることができます。)