假设处理器只有' fadd'和' fmul'符合IEEE-754标准的操作(不是' dot'或' fma'指令)。点产品操作的简单实现将实现最差的精度。例如,对于长度为3的向量:
dot(vec_a, vec_b) = vec_a.x*vec_b.x + vec_a.y*vec_b.y + vec_a.z*vec_b.z
这是我的分析,但我不确定它是否正确: 对于长度为N的向量,存在N次乘法和N-1次加法,导致2N-1个浮点运算。在最坏的情况下,对于每个操作,表示对于准确的结果来说太小,因此中间结果将被舍入。每次舍入都会增加0.5 ULP误差。所以最大误差是(2N-1)* 0.5 = N-1/2 ULP?
答案 0 :(得分:4)
您的推理不适用于添加:如果a
和b
已经不准确,每个0.5 ULP且a
接近-b
,则相对准确度为a + b
可以是terrible,比1.5 ULP差得多。事实上,如果没有关于向量计算点积的更多信息,就无法保证结果的相对准确性。
当只有乘法时,你的推理线是可以的,但它忽略了复合错误。
考虑以下等式:(a + e a )(b + e b )= ab + ae b + be a + e a e b 。
如果你假设a和b都在1和2之间,那么两个结果相乘后的总相对误差已经精确到0.5 ULP,每个只能粗略地估计为1 ULP,并且仍然忽略了误差项e a e b 以及乘法本身的误差。使浮点乘法的结果大约为1.5 ULP总相对误差,这只是一个粗略的平均值,而不是声音最大值。
这些colleagues of mine已经形式化并证明了双精度浮点数积的准确性概念。将结果翻译成英语的是,如果每个向量分量都以1.0
为界,那么点积的最终结果精确到NMAX * B,其中NMAX是向量的维数,B是a恒定取决于NMAX。链接页面上提供了一些值:
NMAX 10 100 1000 B 0x1.1p-50 0x1.02p-47 0x1.004p-44
在他们的结果中,您可以用1.0
替换任何 2的 P的功率,以确保没有溢出,然后点积的绝对误差变为NMAX * B * P 2 。循环不变量分别变为:
@ loop invariant \abs(exact_scalar_product(x,y,i)) <= i * P * P;
@ loop invariant \abs(p - exact_scalar_product(x,y,i)) <= i * B * P * P;
答案 1 :(得分:4)
与许多FP误差分析一样,误差很大程度上取决于输入的最大幅度。在这种情况下,粗略和准备好的错误界限是2 * FLT_EPS * dot(abs(vec_a), abs(vec_b))
,其中abs
表示向量的元素方向绝对值。