c - GCC 的 sqrt() 编译后如何工作?使用哪种root方法?牛顿-拉夫森?
问题描述
sqrt()
只是对 GCC 上的 math.h标准感到好奇。sqrt()
我使用 Newton-Raphson编写了自己的代码来完成它!
解决方案
是的,我知道 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 位慢,以及增加基数。
或许还能看到
- Intel x86 处理器的整数除法算法——Merom 的 Radix-2 和 Radix-4 除法器被 Penryn 的 Radix-16 取代。(Core2 65nm 与 45nm)
- https://electronics.stackexchange.com/questions/280673/why-does-hardware-division-take-much-longer-than-multiplication
- https://scicomp.stackexchange.com/questions/187/why-is-division-so-much-more-complex-than-other-arithmetic-operations
但是不管硬件如何工作,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
性能通常取决于数据。(通常更重要的位或更大的结果需要更长的时间)。
推荐阅读
- javascript - 如何在 Netlify lambda 函数中从 Hugo 网站上的 Google Calendar API 获取请求
- sql - 使用 PASSWORD_VERIFY_FUNCTION 更改配置文件返回无效的函数名称
- reactjs - 使用 Material UI 进行主题嵌套
- java - Java 等价于 C++ Botan 函数调用
- r - 文件处理时间长
- mysql - AWS Aurora Auto Scaling 导致 mysqld_stmt_execute 的参数不正确
- angular - Angular7 性能
- performance - 如何在flutter中调用接口
- sql-server - SQL Server:在使用双 openquery 的查询中向 concat 参数发出问题
- python - 有没有办法通过索引另一个数据帧中的值来从数据帧中选择值