向量双-双浮点运算

时间:2019-04-19 08:57:37

标签: floating-point double vectorization precision

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

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

1 个答案:

答案 0 :(得分:3)

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

# 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而产生的错误结果可能始终带有负号,因此取最大值可能总是会提取正确的结果。 (在夜晚的这个时候,我不能保证在这种情况下这是有效的,但是对于某些操作,一般的做法是。)

另一种可能是比较向量{x.hi, y.hi} > {y.hi, x.hi}以形成位掩码。 (这是伪代码,而不是Julia语法。)位掩码与可能结果对的按位与将保留正确的结果,并将不正确的所有位设置为零。然后,通过按位“或”来简化掩码向量可得到正确的结果。不需要分支。

给定的ISA可能还有其他可行的技巧,例如条件指令。或者还有Dekker算法以外的其他算法。