首页 > 解决方案 > GCC 的 sqrt() 编译后如何工作?使用哪种root方法?牛顿-拉夫森?

问题描述

sqrt()只是对 GCC 上的 math.h标准感到好奇。sqrt()我使用 Newton-Raphson编写了自己的代码来完成它!

标签: cfunctionmathassemblysqrt

解决方案


是的,我知道 fsqrt。但是CPU是怎么做到的呢?我无法调试硬件

现代 CPU 中的典型 div/sqrt 硬件使用 2 基数的幂来一次计算多个结果位。例如http://www.imm.dtu.dk/~alna/pubs/ARITH20.pdf提供了 Radix-16 div/sqrt ALU 的设计细节,并将其与 Penryn 中的设计进行了比较。(他们声称延迟更低,功耗更低。)我看了看图片;看起来一般的想法是做某事并通过乘法器和加法器迭代地反馈结果,基本上就像长除法一样。而且我认为类似于您在软件中进行一次位划分的方式。

英特尔 Broadwell 推出了 Radix-1024 div/sqrt 单元。 这个关于 RWT 的讨论询问了 Penryn (Radix-16) 和 Broadwell 之间的变化。例如,扩大 SIMD 向量除法器,使 256 位除法比 128 位慢,以及增加基数。

或许还能看到


但是不管硬件如何工作,IEEE 要求sqrt(和 mul/div/add/sub)给出正确的舍入结果,即错误 <= 0.5 ulp,所以你不需要知道它是如何工作的,只需要知道性能。这些操作是特殊的,其他函数喜欢log并且sin没有这个要求,并且真正的库实现通常不是那么准确(对于 Pi/2 附近的输入, x87fsin绝对不是那么准确,在这种情况下,范围缩小的灾难性取消会导致潜在的巨大相对误差。)

请参阅https://agner.org/optimize/以获取 x86 指令表,包括标量和 SIMD sqrtsd/sqrtss及其更广泛版本的吞吐量和延迟。我收集了浮点除法与浮点乘法的结果

对于非 x86 硬件 sqrt,您必须查看其他供应商发布的数据或测试过的人的结果。

与大多数指令不同,sqrt性能通常取决于数据。(通常更重要的位或更大的结果需要更长的时间)。


推荐阅读