7

私が書いているオーディオ処理を実行する SSE メソッドに問題があります。ここにある Intel の論文に基づいて、SSE ランダム関数を実装しました。

http://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/

また、SSE を使用して Float から S16 への変換を実行するメソッドもあります。変換は次のように非常に簡単に実行されます。

unsigned int Float_S16LE(float *data, const unsigned int samples, uint8_t *dest)
{
  int16_t *dst = (int16_t*)dest;
  const __m128 mul = _mm_set_ps1((float)INT16_MAX);
   __m128 rand;
  const uint32_t even = count & ~0x3;
  for(uint32_t i = 0; i < even; i += 4, data += 4, dst += 4)
  {
    /* random round to dither */
    FloatRand4(-0.5f, 0.5f, NULL, &rand);

    __m128 rmul = _mm_add_ps(mul, rand);
    __m128 in = _mm_mul_ps(_mm_load_ps(data),rmul);
    __m64 con = _mm_cvtps_pi16(in);

    memcpy(dst, &con, sizeof(int16_t) * 4);
  }
}

FloatRand4 は次のように定義されます。

static inline void FloatRand4(const float min, const float max, float result[4], __m128 *sseresult = NULL)
{
  const float delta  = (max - min) / 2.0f;
  const float factor = delta / (float)INT32_MAX;
  ...
}

結果が返され、sseresult != NULL未使用の場合。これは最初のループでは完全に機能しますが、次のループでは. 行をコメントアウトすると、問題はなくなります。__m128resultdelta-1.#INF1.0__m64 con = _mm_cvtps_pi16(in);

FPUが不明な状態になっていると思います。

4

2 に答える 2

9

SSE 整数演算と (通常の) 浮動小数点演算の混合。両方が同じレジスタで動作しているため、奇妙な結果が生じる可能性があります。使用する場合:

_mm_empty()

FPU が正しい状態にリセットされます。Microsoft は、いつ EMMS を使用するかについてのガイドラインを持っています

于 2012-01-29T10:54:12.603 に答える
1
  • _mm_load_ps は、アライメントされたロードを行うことが保証されていません。float* データは 16 バイトではなく 4 バイトにアラインできます _ => _mm_loadu_ps
  • memcpy はおそらく SSE で達成された利点を殺します。__m64 には store コマンドを使用する必要がありますが、ここでもアライメントに注意してください。アライメントされていない __m64 のストリームまたはストアを行うことが不可能な場合は、_m128i 内に保持して _mm_maskmoveu_si128 でマスク書き込みを行うか、それらの 8 バイトを手動で保存します。

http://msdn.microsoft.com/en-us/library/bytwczae.aspx

于 2012-01-29T10:53:25.927 に答える