“求和顺序仍会影响两个重心和,必要时可结合成对或补偿求和;但补偿不能修复溢出的权重或病态节点。输入输出、节点尺度和求和策略应在实现说明中同时给出。”
形式陈述 ​
给定浮点序列
朴素顺序求和按固定次序递推
若
同号数据的该因子为
成对求和把输入组织成近似平衡的二叉树,先求相邻小组,再逐层合并。它仍使用
的界。树形结构也适合并行归约,但不同分块和调度会改变加法树,因而可能改变末位结果。
Kahan 补偿求和额外维护一个校正量
估计本轮被舍掉的低位,最后更新
“更准确”不是唯一目标。准确求和追求接近精确和或正确舍入结果;可复现求和要求线程数、分块或执行顺序改变时仍给同一位模式;高吞吐归约则关心带宽、向量化和同步成本。三者可以兼得一部分,却不是同一个规格,必须在算法说明中分别写清。
直觉 ​
顺序累加像不断往同一个刻度有限的量杯里加液体。当部分和已经很大,新加入的小量若小于当前一个刻度的一半,就会在舍入时完全消失。成对求和先让相近尺度的小量彼此合并,补偿求和则另放一个小杯子保存刚才没能倒进去的部分。
加法在实数中满足结合律,浮点加法却把每个括号位置变成一次舍入。重排不是改变数学目标,而是选择误差经过哪棵计算树传播;这也是串行代码、向量化实现和并行归约可能得到不同末位的原因。
例子与边界 ​
一次 binary64 实验从数值
相对于高精度参考舍入值的绝对误差约为
同一输入用 Kahan 求和得到打印值
顺序依赖可由三项看清:
从左到右时,
编译器的重新结合、SIMD 分块和 GPU 归约可能合法地改变加法树。需要逐位可复现时,必须固定归约结构或使用专门的可复现算法;只声明“Kahan”而允许编译器破坏其运算顺序,同样不能保留补偿语义。
推论与应用 ​
前缀和在精确结合运算下关注并行依赖结构,浮点输入还要同时说明每个前缀采用的加法树。点积、数值积分、统计均值、概率期望估计和快速 Fourier 变换都把大量局部结果归约为和,因此会继承本页的条件因子与顺序问题。
选择算法时可先看三个事实:项数是否足以让线性误差增长显著,正负抵消是否使精确和远小于绝对值之和,以及执行环境是否要求跨并行布局复现。没有这些信息,单独比较一次运行的最后几位无法判断方法是否可靠。
参考资料
- Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd ed., SIAM, 2002, Ch. 4.
- David Goldberg, “What Every Computer Scientist Should Know About Floating-Point Arithmetic,” ACM Computing Surveys 23(1), 1991.
- Takeshi Ogita, Siegfried M. Rump, and Shin’ichi Oishi, “Accurate Sum and Dot Product,” SIAM Journal on Scientific Computing 26(6), 2005.