按位运算对浮点有用性

Bitwise operation on a floating point usefulness

我注意到有一条用于浮点的 SSE 指令,这让我感到疑惑。您可以对 fp/integer 联合中的标量执行相同的操作。

我突然想到,如果对浮点数组的分量进行按位或运算,您可以通过查看结果的符号位来快速确定它们是否为负数。

浮点值的按位运算还有哪些其他用途?

很多。例如,当您只需要对像 AVX 这样的仅浮点指令集进行按位运算时,这些就变得非常方便了。

另一个应用:制作常量。你可以在table 13.10和13.11中看到很多例子Agner Fog's optimization guide for x86 platforms。一些例子:

pcmpeqd xmm0, xmm0
psrld   xmm0, 30   ; 3 (32-bit)

pcmpeqd xmm0, xmm0 ; -1

pcmpeqw xmm0, xmm0 ; 1.5f
pslld   xmm0, 24
psrld   xmm0, 2

pcmpeqw xmm0, xmm0 ; -2.0f
pslld   xmm0, 30

您也可以使用它来检查浮点值是否为 2 的幂。

其他的一些应用如Harold说:取绝对值和负绝对值,复制符号,muxing...为了便于理解,我将在单个数据中进行演示

// Absolute:
abs = x & ~(1U << 31);
// Muxing
v = (x & mask) | (y & ~mask); // v = mask ? x : y; with mask = 0 or -1
// Copy sign
y = (y & ~(1U << 31)) | (x & (1U << 31));

它可用于使用所谓的 "double double" arithmetic 扩展浮点精度,特别是当您无法访问融合乘加 (FMA) 指令时。

如果你有两个浮点数的后半部分为零,那么它们的乘积是精确的。所以一个常见的技巧是将浮点数的一部分归零,从原始数字中减去它,你有两个数字总和为原始值,但每个数字只使用一半的尾数。通过适当安排操作顺序,您可以获得两个总和为精确乘积的浮点数:例如,请参见 Dekker (1971).

我使用 Julia 进行了一些粗略的速度测试 here:浮点 AND 比移至整数寄存器、使用整数 AND 并移回至少快 50%。