GCC的sqrt()编译后是如何工作的?root使用的是哪种方法?Newton-Raphson?

rmbxnbpk  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(100)

只是对GCC上math.h的标准sqrt()感到好奇,我用Newton-Raphson编写了自己的sqrt()

pgvzfuti

pgvzfuti1#

是的,我知道fsqrt。但是CPU是怎么做的?我不能调试硬件
现代CPU中的典型div/sqrt硬件使用2的幂基数一次计算多个结果位。例如http://www.imm.dtu.dk/~alna/pubs/ARITH20.pdf提供了一个Radix-16 div/sqrt ALU的设计细节,并将其与Penryn中的设计进行了比较。(他们声称更低的延迟和更少的功率。)我看了看图片;看起来一般的想法是做一些事情,并通过乘法器和加法器迭代地反馈结果,基本上就像长除法一样。我认为类似于你在软件中做一次一位除法的方式。
Intel Broadwell引入了Radix-1024 div/sqrt单元。This discussion on RWT询问Penryn(Radix-16)和Broadwell之间的变化。例如,加宽SIMD向量除法器,使256位除法比128位除法慢,以及增加基数。
也许还能看到

但无论硬件如何工作,IEEE要求sqrt(和穆尔/div/add/sub)来给予一个 * 正确舍入的 * 结果,即error <= 0.5 ulp,所以你不需要知道它是如何工作的,只需要知道性能。这些操作是特殊的,其他函数如logsin没有 * 这个要求,而真实的库实现通常并不那么准确(对于接近Pi/2的输入,x87 fsin is definitely not that accurate,其中范围缩减中的灾难性取消会导致潜在的 * 巨大 * 相对误差)。
有关x86指令表,包括标量和SIMD sqrtsd/sqrtss及其更广泛版本的吞吐量和延迟,请参见https://agner.org/optimize/
对于非x86硬件sqrt,你必须查看其他供应商发布的数据,或者测试人员的测试结果。
与大多数指令不同,sqrt的性能通常依赖于数据(通常更高的有效位或更大的结果需要更长的时间)。

gorkyyrv

gorkyyrv2#

sqrt是由C定义的,所以很可能你必须在glibc中查找。
您没有指定您要求的架构,所以我认为假设x86-64是安全的。如果是这种情况,它们定义在:

tl;dr它们可以通过调用x86-64平方根指令sqrts{sd}

此外,为了便于讨论,如果你启用了快速数学(如果你关心结果精度,你可能不应该),你会看到大多数编译器实际上会内联调用并直接发出sqrts{sd}指令:
https://godbolt.org/z/Wb4unC

相关问题