2016-07-14 1 views
0

SSE4組み込み関数を大量に使用するコードを移植しています。 SSE以外の実装がありますが、SSE2だけのCPUでも高速な機能を使用できるようにしたいと考えています。_mm_insert_epi32に相当するSSE2はありますか?

誰か_mm_insert_epi32ための効率的な交換をお勧めでした - 私が思うに、私は他のすべては、すでにカバーされてしまったが...実際には、第二および関数の3番目の引数は、私の場合はゼロです:

foo = _mm_insert_epi32(vec, 0, 0); 

答えて

2

実際にベクトルの下位要素をゼロにしたいのですか?それは_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/タグwikiを参照してください。

関連する問題