单精度与双精度浮点

计算科学 矩阵 线性求解器 精确
2021-12-15 00:43:06

单精度浮点数占用了一半的内存,并且在现代机器上(甚至在 GPU 上似乎)可以用它们以几乎两倍于双精度的速度完成操作。我发现的许多 FDTD 代码专门使用单精度算术和存储。是否有经验法则表明何时可以使用单精度来求解大规模稀疏方程组?我认为它必须在很大程度上取决于矩阵条件数。

此外,是否有任何有效的技术在必要时使用双精度,在不需要双精度的情况下使用单精度。例如,我认为对于矩阵向量乘法或向量点积,将结果累积在双精度变量中可能是个好主意(以避免取消错误),但是各个条目要相互相乘可以使用单精度相乘。

现代 FPU 是否允许从单精度 (float) 无缝转换为双精度 (double),反之亦然?还是这些昂贵的操作?

3个回答

对于所有重要的问题(即,对于那些对性能很重要的问题),您拥有的几乎所有内存都将在矩阵中,而在向量中则相对较少。例如,对于 Stokes 方程的 3d Taylor-Hood 元素,矩阵中每行有几百个元素,这大大超过了向量所需的内存量。因此,我们尝试了将矩阵存储为浮点数并将向量存储为双精度数的想法。我不记得我们的计时结果,但我确信我们没有看到四舍五入等问题。所以这种方法肯定有效。

关于这个主题的一篇不错的论文是使用混合精度算法加速科学计算

我的建议是主要关注内存消耗,以决定何时使用单精度(浮点数)。因此,FDTD 计算的批量数据应该使用浮点数,但我会将问题描述本身(如几何、材料参数、激发条件)和所有相关元数据保留为双精度。

我会保持所有性能不重要,也不会对计算进行深入分析。特别是,我会将多边形数据和其他几何描述保持双倍(如果可能的话,甚至可能是整数),因为经验告诉你永远不会让代码的计算几何部分完全健壮,即使理论上是可能的。

我要保留的第三部分是分析计算,包括使用非对称特征值分解的捷径。例如,我有一个分段定义的旋转对称二维函数,我需要它的傅里叶变换。将有各种涉及 FFT 的数值方法和适当的“分析低通滤波器”来“有效地”获得它。因为它的性能不重要,所以我使用了一个涉及 Bessel 函数的“精确”分析表达式。由于这是一开始的捷径,而且我不会花任何时间分析我复杂公式的错误传播,因此我最好使用双精度进行计算。(结果仍然证明,该公式只有一些解析等价表达式可用,