7

我在编写执行音频处理的 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未使用。这在第一个循环上完美执行,但在下一个循环上变为而不是. 如果我注释掉该行,问题就会消失。__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* 数据​​可以对齐到 4 个字节而不是 16 个 _ => _mm_loadu_ps
  • memcpy 可能会扼杀使用 SSE 实现的优势,您应该对 __m64 使用存储命令,但在这里再次注意对齐。如果无法执行未对齐的流或存储 __m64,我会将其保存在 _m128i 中并使用 _mm_maskmoveu_si128 进行屏蔽写入或手动存储这 8 个字节。

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

于 2012-01-29T10:53:25.927 回答