CC++中双重快速反平方

CC++中双重快速反平方,第1张

概述最近我正在剖析一个程序,其中热点绝对是这样的 double d = somevalue();double d2=d*d;double c = 1.0/d2 // HOT SPOT 因为我只需要值c,所以不使用值d2.前段时间我已经阅读了关于快速反平方根的Carmack方法,显然不是这样,但是我想知道一个类似的算法是否可以帮助我计算1 / x ^ 2. 我需要相当准确的精度,我检查过我的程序 最近我正在剖析一个程序,其中热点绝对是这样的
double d = somevalue();double d2=d*d;double c = 1.0/d2   // HOT SPOT

因为我只需要值c,所以不使用值d2.前段时间我已经阅读了关于快速反平方根的Carmack方法,显然不是这样,但是我想知道一个类似的算法是否可以帮助我计算1 / x ^ 2.

我需要相当准确的精度,我检查过我的程序没有使用gcc -ffast-math选项给出正确的结果. (g -4.5)

解决方法 快速平方根等的技巧通过牺牲精度得到他们的表现. (嗯,大多数.)

您确定需要双重精度吗?您可以轻松地牺牲精度:

double d = somevalue();float c = 1.0f / ((float) d * (float) d);

在这种情况下,1.0f绝对是强制性的,如果使用1.0,那么您将获得双精度.
您是否尝试在编译器上启用“马虎”数学?在GCC上,您可以使用-offast-math,其他编译器也有类似的选项.对于您的应用程序来说,数学可能不够好. (编辑:我没有看到结果汇编中有任何区别.)
>如果您使用GCC,是否考虑使用-mrecip?有一个“相互估计”功能只有大约12位的精度,但是要快得多.您可以使用Newton-Raphson方法来提高结果的精度. -mrecip选项将导致编译器为您自动生成相互估计和Newton-Raphson步骤,但如果要精细调整性能 – 精度折衷,您可以随时自行编写程序集. (牛顿 – 拉夫逊收敛非常快)(编辑:我无法让GCC生成RcpsS,见下文)

我发现一篇博客文章(source)讨论了您正在经历的确切问题,作者的结论是,像Carmack方法这样的技术与RcpsS指令(GCC使用的-mrecip标志)不具竞争力.

分区可能如此缓慢的原因是因为处理器通常只有一个分割单元,而且通常不是流水线的.因此,您可以在管道中同时执行几个乘法运算,但是在上一个分区完成之前不能分配.

不工作的技巧

> Carmack的方法:在现代处理器上已经过时了,它们具有相互的估计 *** 作码.对于倒数,我看到的最好的版本只能提供一点精度 – 与RcpsS的12位相比,没有什么.我认为这是巧合,这个伎俩对于相互平方根有好的效果;巧合不大可能重复.
>重新标记变量.就编译器而言,1.0 /(x * x)和double x2 = x * x之间的差异很小. 1.0 / X2.如果您发现一个编译器为两个版本生成不同的代码,即使达到最低级别的优化,我也会感到惊讶.
>使用pow. pow库函数是一个完整的怪物.随着GCC的关闭数学关闭,图书馆的电话是相当昂贵的.随着GCC的数学打开,您将获得与pow(x,-2)完全相同的汇编代码,就像1.0 /(x * x)一样,所以没有任何好处.

更新

以下是双精度浮点值的反平方的牛顿 – 拉夫逊逼近的例子.

static double invsq(double x){    double y;    int i;    __asm__ (        "cvtpd2ps %1,%0\n\t"        "rcpss %0,%0\n\t"        "cvtps2pd %0,%0"        : "=x"(y)        : "x"(x));    for (i = 0; i < RECIP_ITER; ++i)        y *= 2 - x * y;    return y * y;}

不幸的是,在我的电脑上使用RECIP_ITER = 1的基准测试,它比简单版本1.0 /(x * x)略慢(约5%).它的速度更快(2x快),但是只有12位的精度.我不知道12位是否足够你.

我认为这里的一个问题是这个微型优化太小了;在这个规模上,编译器作者与装配黑客几乎相同.也许如果我们有更大的图景,我们可以看到一种方法来加快速度.

例如,你说过 – 数学造成了不合理的精度损失;这可能表示您正在使用的算法中的数值稳定性问题.利用算法的正确选择,可以通过float而不是double来解决许多问题. (当然,你可能只需要24位以上,我不知道.)

如果要并行计算其中的几个,我怀疑RcpsS方法是否发光.

总结

以上是内存溢出为你收集整理的C/C++中双重快速反平方全部内容,希望文章能够帮你解决C/C++中双重快速反平方所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1253715.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存