快速近似浮点除法
Fast approximate float division
本文关键字:除法 更新时间:2023-10-16
在现代处理器上,浮点除法比浮点乘法慢一个数量级(以倒数吞吐量衡量)。
我想知道,在给定某些假设和容差水平的情况下,是否有任何算法可以计算x/y
的快速近似值。例如,如果您假设0<x<y
,并且愿意接受真实值10%以内的任何输出,是否有比内置FDIV操作更快的算法?
我希望这会有所帮助,因为这可能与你想要的一样接近。
__inline__ double __attribute__((const)) divide( double y, double x ) {
// calculates y/x
union {
double dbl;
unsigned long long ull;
} u;
u.dbl = x; // x = x
u.ull = ( 0xbfcdd6a18f6a6f52ULL - u.ull ) >> (unsigned char)1;
// pow( x, -0.5 )
u.dbl *= u.dbl; // pow( pow(x,-0.5), 2 ) = pow( x, -1 ) = 1.0/x
return u.dbl * y; // (1.0/x) * y = y/x
}
另请参阅:
另一篇关于倒数近似的帖子
维基百科页面。
FDIV通常比FMUL慢异常只是b/c它不能像乘法一样管道化,并且需要多个clk循环来进行迭代收敛HW搜索过程。
最简单的方法是简单地认识到除法只不过是被除数y
和除数x
的倒数的乘积。不那么直接的部分是记住浮点值CCD_ 5&其逆CCD_ 6近似于该新尾数CCD_。这给出了反函数的粗略分段线性近似,然而,通过使用迭代牛顿寻根方法来改进该近似,我们可以做得更好。
设w = f(x) = 1/x
,通过用w
或x = f^(-1)(w) = 1/w
求解x
,得到该函数f(x)
的逆。为了用寻根方法改进输出,我们必须首先创建一个函数,其零反映所需的输出,即g(w) = 1/w - x, d/dw(g(w)) = -1/w^2
。
w[n+1]= w[n] - g(w[n])/g'(w[n]) = w[n] + w[n]^2 * (1/w[n] - x) = w[n] * (2 - x*w[n])
w[n+1] = w[n] * (2 - x*w[n]), when w[n]=1/x, w[n+1]=1/x*(2-x*1/x)=1/x
然后这些组件相加得到最后一段代码:
float inv_fast(float x) {
union { float f; int i; } v;
float w, sx;
int m;
sx = (x < 0) ? -1:1;
x = sx * x;
v.i = (int)(0x7EF127EA - *(uint32_t *)&x);
w = x * v.f;
// Efficient Iterative Approximation Improvement in horner polynomial form.
v.f = v.f * (2 - w); // Single iteration, Err = -3.36e-3 * 2^(-flr(log2(x)))
// v.f = v.f * ( 4 + w * (-6 + w * (4 - w))); // Second iteration, Err = -1.13e-5 * 2^(-flr(log2(x)))
// v.f = v.f * (8 + w * (-28 + w * (56 + w * (-70 + w *(56 + w * (-28 + w * (8 - w))))))); // Third Iteration, Err = +-6.8e-8 * 2^(-flr(log2(x)))
return v.f * sx;
}
相关文章:
- 在除法中不需要四舍五入
- 在TFHE(完全快速同态加密)上执行除法
- 使用 int 表示浮点除法 C++
- 而循环:简单的除法程序输出零,不明白为什么
- 余数除法和不允许除以零 (c++) 时遇到问题
- 如何确定涉及 C++ 中除法的算术表达式的数据类型
- 如何使用除法和for_each?
- C++:奇怪的除法输出
- 分配给浮点数的积分文字除法 - 为什么结果是错误的?
- 除法函数返回错误的值
- 检查向量是否使用除法和阻抗算法进行排序
- 不使用算术运算符的除法
- C++编译器能在编译时计算出文字的除法结果吗
- 浮点 由于除法语句而导致的 c++ 异常
- 特征矩阵向量除法
- 在早期的 C 和 C++ 编译器中,手动位移位与乘法和除法的相关性如何?
- 用除法反转向量的元素
- 按运行时常量值重复整数除法
- 将 int 128 除法提升为浮点数
- 用于 3D 矢量的高效除法运算符