2012-02-06 24 views
11

SSEを使用して、符号なしの短い配列の配列を浮動小数点に変換したいと考えています。のは、私がY2におけるY1 &次の4 uint16の最初の4 uint16のを望んでSSE:短い整数を浮動小数点に変換する

__m128i xVal;  // Has 8 16-bit unsigned integers 
__m128 y1, y2; // 2 xmm registers for 8 float values 

を言ってみましょう。 使用するsse組み込み関数を知る必要があります。

答えて

17

あなたが最初に浮かぶようにこれらのベクトルの各々を変換し、その後、32ビット符号なし整数型の二つのベクトルに8×16ビットの符号なしshortのあなたのベクトルを解凍する必要があります。

__m128i xlo = _mm_unpacklo_epi16(x, _mm_set1_epi16(0)); 
__m128i xhi = _mm_unpackhi_epi16(x, _mm_set1_epi16(0)); 
__m128 ylo = _mm_cvtepi32_ps(xlo); 
__m128 yhi = _mm_cvtepi32_ps(xhi); 
+0

ありがとう..この作品は – krishnaraj

+0

ですが、 d _mm_set1_epi16の代わりに1つの_mm_setzero_si128()を使用します。 – Magnus

+0

@Magnus:私は、生成されたコードが少なくともどちらかといえば、まともなコンパイラと同じであることがわかります。 –

6

私は少し使用することをお勧め異なるバージョン:

static const __m128i magicInt = _mm_set1_epi16(0x4B00); 
static const __m128 magicFloat = _mm_set1_ps(8388608.0f); 

__m128i xlo = _mm_unpacklo_epi16(x, magicInt); 
__m128i xhi = _mm_unpackhi_epi16(x, magicInt); 
__m128 ylo = _mm_sub_ps(_mm_castsi128_ps(xlo), magicFloat); 
__m128 yhi = _mm_sub_ps(_mm_castsi128_ps(xhi), magicFloat); 

アセンブリレベルでは、ポール・Rバージョンからの唯一の違いは_mm_sub_ps(SUBPS命令)の代わりに_mm_cvtepi32_ps(CVTDQ2PS命令)の使用です。 _mm_sub_psは_mm_cvtepi32_psより遅くなることはなく、実際には古いCPUや低電力CPU(Intel AtomとAMD Bobcat)でより高速です

+1

私は完全にこれがより良いと確信していない。 SSE-intからSSE-FPへデータを移動するには、1〜2サイクルのレイテンシヒットが必要です。次に、2つの定数のための2つの余分なレジスタ(または負荷)が必要です。このトリックは、倍精度でより一般的に使用されます。 – Mysticial

+1

CVTDQ2PSにもSSE-INTからSSE-FPへの移行ペナルティがあります。レジスタの増加は問題になる可能性がありますが、周辺のコードに大きく依存しています。 –

+0

そう、私はそれを見落とした。 :) +1 – Mysticial

関連する問題