Texas Instrument CLA 浮点数反转技巧 - 它的目的是什么
Texas Instrument CLA float inverse trick - What is its purpose
我有一段由其他人编写的代码,它在 TI TMS320 命令律加速器上运行。所以它在大小和速度上都进行了优化。
为了得到 1/x,代码总是做这样的事情。
float32 y = __meinvf32(x);
y = y * (2.0f - y*x);
y = y * (2.0f - y*x);
我发现 this thread 提出了类似的建议,但就我而言,最后没有夹紧。
谁能帮我理解这背后的意图是什么?
y = e + 1/x 其中 e 是一些小误差。
所以 (2.0 - y*x) 接近于 1.0 并且具有在每次通过时减少 e 的效果。
艾萨克·牛顿发现了这一点。
__meinvf32(x)
给出 1/x 的近似值,比如 1/x • (1+e),其中 e 是一些小的相对误差。
设y = 1/x • (1+e)。然后,当我们计算 y • (2 − y•x) 时,我们有:
- y • (2 − y•x) =
- (1/x • (1+e)) • (2 − (1/x • (1+e))•x) =
- 1/x • (1+e) • (2 − (1+e)) =
- 1/x • (2 + 2e − (1+e) − e(1+e)) =
- 1/x • (2 + 2e − 1 − e − e − e2) =
- 1/x • (1 − e2).
既然e小,那么e2就更小了。因此,通过计算 y • (2 − y•x) 我们得到 1/ x 比以前更近;相对误差只有 −e2 而不是 e。重复此操作再次改进估计(达到浮点精度的限制)。
通过对初始 e 的边界的一些了解,我们可以计算需要重复多少次才能使估计尽可能接近正确的结果。
我有一段由其他人编写的代码,它在 TI TMS320 命令律加速器上运行。所以它在大小和速度上都进行了优化。
为了得到 1/x,代码总是做这样的事情。
float32 y = __meinvf32(x);
y = y * (2.0f - y*x);
y = y * (2.0f - y*x);
我发现 this thread 提出了类似的建议,但就我而言,最后没有夹紧。
谁能帮我理解这背后的意图是什么?
y = e + 1/x 其中 e 是一些小误差。
所以 (2.0 - y*x) 接近于 1.0 并且具有在每次通过时减少 e 的效果。
艾萨克·牛顿发现了这一点。
__meinvf32(x)
给出 1/x 的近似值,比如 1/x • (1+e),其中 e 是一些小的相对误差。
设y = 1/x • (1+e)。然后,当我们计算 y • (2 − y•x) 时,我们有:
- y • (2 − y•x) =
- (1/x • (1+e)) • (2 − (1/x • (1+e))•x) =
- 1/x • (1+e) • (2 − (1+e)) =
- 1/x • (2 + 2e − (1+e) − e(1+e)) =
- 1/x • (2 + 2e − 1 − e − e − e2) =
- 1/x • (1 − e2).
既然e小,那么e2就更小了。因此,通过计算 y • (2 − y•x) 我们得到 1/ x 比以前更近;相对误差只有 −e2 而不是 e。重复此操作再次改进估计(达到浮点精度的限制)。
通过对初始 e 的边界的一些了解,我们可以计算需要重复多少次才能使估计尽可能接近正确的结果。