向量双双浮点运算

Vector double-double floating point arithmetic

提问人:rwallace 提问时间:4/19/2019 最后编辑:Peter Cordesrwallace 更新时间:6/7/2021 访问量:387

问:

对于某些工作负载,双精度浮点数并不完全足够,因此需要四精度。这在硬件中很少提供,因此解决方法是使用 double-double,其中 128 位数字由一对 64 位数字表示。这不是真正的 IEEE-754 四精度 - 一方面你没有得到任何额外的指数位 - 但在许多方面,它足够接近,并且比纯软件实现快得多。

许多计算机都提供向量浮点运算,最好将这些运算用于双精度运算。这可能吗?特别是,查看 https://github.com/JuliaMath/DoubleDouble.jl/blob/master/src/DoubleDouble.jl double-double 的实现,在我看来,每个算术运算都需要中间至少一个条件分支,我认为这意味着不能使用 SIMD 向量运算,除非我遗漏了什么?

浮点 矢量化 精度 SIMD 双精度双精度算法

评论


答:

3赞 Davislor 4/19/2019 #1

我认为您正在考虑加法和减法的实现,例如:

# Dekker add2
function +{T}(x::Double{T}, y::Double{T})
    r = x.hi + y.hi
    s = abs(x.hi) > abs(y.hi) ? (((x.hi - r) + y.hi) + y.lo) + x.lo : (((y.hi - r) + x.hi) + x.lo) + y.lo
    Double(r, s)
end

在某些体系结构上,解决方案可能是使用 SIMD 指令并行计算两个分支,然后执行操作以检索两者的正确结果。例如,通过从错误的操作数中减去而产生的错误结果可能始终具有负号,因此取最大值可能始终提取正确的结果。(在晚上的这个时候,我不能保证这在这种情况下是有效的,但对于某些操作,一般方法是。x.hi + y.hi

另一种方法是比较向量以形成位掩码。(这是伪代码,不是 Julia 语法。位掩码的按位 AND 和潜在结果对将保持正确结果不变,并将错误 1 的所有位设置为零。然后,用按位 OR 减少掩码向量会产生正确的结果。不需要分支。{x.hi, y.hi} > {y.hi, x.hi}

给定的 ISA 可能具有其他有效的技巧,例如条件指令。或者除了 Dekker 的算法之外,还有其他算法。

评论

2赞 wim 4/19/2019
请注意,在实践中,使用传统的 2sum 算法而不是 Dekker 的 Fast2Sum 可能更有效。传统的 2sum 可以有效地矢量化。例如,请参阅此处:算法 1 和 2