【问题标题】:How to negate (change sign) of the floating point elements in a __m128 type variable?如何对 __m128 类型变量中的浮点元素取反(更改符号)?
【发布时间】:2013-12-03 17:46:33
【问题描述】:

是否有任何单个指令或函数可以invert the sign __m128 中的每个浮点数? 即a = r0:r1:r2:r3 ===> a = -r0:-r1:-r2:-r3?

我知道这可以由_mm_sub_ps(_mm_set1_ps(0.0),a) 完成,但由于_mm_set1_ps(0.0) 是一个多指令函数,它可能不会很慢吗?

【问题讨论】:

标签: c x86 vectorization sse simd


【解决方案1】:

实际上,您的编译器应该能够很好地生成 0.0 的常量向量。它可能只使用_mm_xor_ps,如果您的代码处于循环中,它应该将常量生成提升出循环。所以,最重要的是,使用你最初的想法:

v = _mm_sub_ps(_mm_set1_ps(0.0), v);

或另一个常见的技巧,即:

v = _mm_xor_ps(v, _mm_set1_ps(-0.0));

它只是翻转符号位而不是做减法(不像第一种方法那样安全,因为它不能用 NaN 做正确的事情,但在某些情况下可能更有效)。

【讨论】:

  • 我很确定 xor 可以使用 NaN。 NaN 中的符号位具有无关状态,因此所有 NaN 保持为 NaN,所有非 NaN 保持非 NaN。安静与信号 NaN 由尾数的最高位(不是整个浮点数的最高位)指示。使用xor 通常是最好的。在 AMD 上,xorps 在整数域中运行,因此与 FP 数学指令之间存在绕过延迟,它仍然与 5c subps 的延迟大致相同。
  • 从内存中加载 -0.0 常量可能会缓存未命中。如果需要多个 insn(xorps same,samepcmpeqw same,same(全一)),编译器不喜欢 generate constants on the fly。这个只需要pcmpeqw xmm7,xmm7 / pslld xmm7, 31(请参阅该链接以获取 SSE 绝对值:ANDN 与该掩码,或 AND 与它的逆)
  • 不能用_mm_setzero_ps()替换_mm_set1_ps(0.0)吗?
  • @MarcinPoliczek:是的,使用你喜欢的任何一个 - 无论哪种情况,编译器都会生成相同的代码。
  • 有没有办法处理 0x80000000(即 -2147483648)。我期待 2147483647 结果
猜你喜欢
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
相关资源
最近更新 更多