floating-point - 向量双双浮点运算

标签 floating-point vectorization precision simd double-double-arithmetic

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

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

最佳答案

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

# 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 语法。)位掩码和一对潜在结果的按位 AND 将使正确结果保持不变,并将错误 1 ​​的所有位设置为零。然后,通过按位或减少掩码向量会产生正确的结果。不需要分支。

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

关于floating-point - 向量双双浮点运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55759224/

相关文章:

c++ - std::stringstream 中双输出的默认格式标志(和宽度)是什么?

math - float 学有问题吗?

c# - 为什么要使用这种笨拙的方式将 float 舍入为整数?

python - 向量化 numpy 索引并应用函数构建矩阵

python - 如何以矢量化方式而不是使用循环来编写代码?

arm - ARM 是否支持 64 位 float 的 SIMD 操作?

floating-point - 如何仅使用稳定的标准库将 f16 解码为 f32?

python - 如何显示带有两位小数的 float ?

c - 将具有整数值的 double 值转换为整数时,是否保证执行 'properly' ?

python - 加速 numpy 中的 for 循环