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組み込み関数を知る必要があります。
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組み込み関数を知る必要があります。
あなたが最初に浮かぶようにこれらのベクトルの各々を変換し、その後、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);
私は少し使用することをお勧め異なるバージョン:
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)でより高速です
ありがとう..この作品は – krishnaraj
ですが、 d _mm_set1_epi16の代わりに1つの_mm_setzero_si128()を使用します。 – Magnus
@Magnus:私は、生成されたコードが少なくともどちらかといえば、まともなコンパイラと同じであることがわかります。 –