gpt4 book ai didi

c++ - 优化定点平方

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:06:22 24 4
gpt4 key购买 nike

我做了一个我认为不错的定点平方根算法:

template<int64_t M, int64_t P>
typename enable_if<M + P == 32, FixedPoint<M, P>>::type sqrt(FixedPoint<M, P> f)
{
if (f.num == 0)
return 0;
//Reduce it to the 1/2 to 2 range (based around FixedPoint<2, 30> to avoid left/right shift branching)
int64_t num{ f.num }, faux_half{ 1 << 29 };
ptrdiff_t mag{ 0 };
while (num < (faux_half)) {
num <<= 2;
++mag;
}

int64_t res = (M % 2 == 0 ? SQRT_32_EVEN_LOOKUP : SQRT_32_ODD_LOOKUP)[(num >> (30 - 4)) - (1LL << 3)];
res >>= M / 2 + mag - 1; //Finish making an excellent guess
for (int i = 0; i < 2; ++i)
// \ | /
// \ | /
// _| V L
res = (res + (int64_t(f.num) << P) / res) >> 1; //Use Newton's method to improve greatly on guess
// 7 A r
// / | \
// / | \
// The Infamous Time Eater
return FixedPoint<M, P>(res, true);
}

然而,在分析之后(在 Release模式下)我发现这里的除法占据了这个算法花费的时间的 83%。我可以通过用乘法代替除法来加速 6 倍,但这是错误的。不幸的是,我发现整数除法比乘法慢得多。有什么办法可以优化吗?

如果需要这张表。

const array<int32_t, 24> SQRT_32_EVEN_LOOKUP = {
0x2d413ccd, //magic numbers calculated by taking 0.5 + 0.5 * i / 8 from i = 0 to 23, multiplying by 2^30, and converting to hex
0x30000000,
0x3298b076,
0x3510e528,
0x376cf5d1,
0x39b05689,
0x3bddd423,
0x3df7bd63,
0x40000000,
0x41f83d9b,
0x43e1db33,
0x45be0cd2,
0x478dde6e,
0x49523ae4,
0x4b0bf165,
0x4cbbb9d6,
0x4e623850,
0x50000000,
0x5195957c,
0x532370b9,
0x54a9fea7,
0x5629a293,
0x57a2b749,
0x59159016
};

SQRT_32_ODD_LOOKUP 只是 SQRT_32_EVEN_LOOKUP 除以 sqrt(2)

最佳答案

重新发明轮子,真的,但不是很好。正确的解决方案是使用 NR 计算 1/sqrt(x),然后乘以一次得到 x/sqrt(x) - 只需检查 x= =0 放在前面。

之所以如此好,是因为 y=1/sqrt(x) 的 NR 步骤只是 y = (3-x*y*y)*y/2。这就是所有直接的乘法。

关于c++ - 优化定点平方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36077485/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com