簡體   English   中英

SSE內在函數導致正常的float操作返回-1。#INV

[英]SSE intrinsics cause normal float operation to return -1.#INV

我正在編寫一個執行音頻處理的SSE方法的問題。 我在這里基於英特爾的論文實現了一個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 ,則返回__m128結果, result未使用。 這在第一個循環上表現完美,但在下一個循環中, delta變為-1.#INF而不是1.0 如果我注釋掉__m64 con = _mm_cvtps_pi16(in); 問題消失了。

我認為FPU正在進入一個未知的狀態。

混合SSE整數算術和(常規)浮點數學。 可以產生奇怪的結果,因為它們都在相同的寄存器上運行。 如果您使用:

_mm_empty()

FPU重置為正確狀態。 Microsoft提供了何時使用EMMS的指南

  • _mm_load_ps不保證執行對齊加載。 float * data可以對齊到4個字節而不是16 _ => _mm_loadu_ps
  • memcpy可能會破壞使用SSE實現的優勢,你應該使用__m64的存儲命令,但在這里再次處理對齊。 如果不可能做一個未對齊的流或__m64的存儲,我要么將它保存在_m128i中並使用_mm_maskmoveu_si128進行掩碼寫入或手動存儲這8個字節。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM