c ++ <cmath> SQRT()</cmath>的实际计算复杂度

时间:2011-07-30 16:09:09

标签: c++ complexity-theory sqrt cpu-cycles cpu-time

之间的CPU周期(或者,实质上是'速度')有什么不同
 x /= y;

 #include <cmath>
 x = sqrt(y);
编辑:我知道操作不等同,我只是随意提出x /= y作为x = sqrt(y)

的基准

3 个答案:

答案 0 :(得分:9)

您的问题的答案取决于您的目标平台。假设您正在使用最常见的x86 cpu,我可以给你这个链接http://instlatx64.atw.hu/这是一个测量指令延迟的集合(CPU在获得参数后获取结果需要多长时间)以及它们如何被流水线化许多x86和x86_64处理器。如果您的目标不是x86,您可以尝试自己测量成本或咨询CPU文档。

首先,您应该获得操作的反汇编程序(来自编译器,例如gcc:gcc file.c -O3 -S -o file.asm或通过编译二进制文件的解集,例如在调试器的帮助下)。 请记住,在您的操作中,需要加载和存储一个值,该值必须另外计算。

以下是friweb.hu的两个例子:

对于SQRT的Core 2 Duo E6700延迟(L)(x87,SSE和SSE2版本)

  • 32位浮点数29个刻度; 58位为64位双倍; 69蜱为80位长的双倍;
DIVIDE的

(浮点数):

  • 32位的18个滴答; 64位为32位; 38位为80位

对于较新的处理器,DIV和SQRT的成本较低且几乎相同,例如:对于Sandy Bridge Intel CPU:

浮点SQRT

  • 14位,为32位; 64位为21位; 24位为80位

浮点DIVIDE是

  • 14位,为32位; 64位为22位; 24位为80位

SQRT甚至比32位更快。

所以:对于较旧的CPU,sqrt本身比fdiv慢30-50%;对于较新的CPU,成本是相同的。 对于较新的CPU,两种操作的成本都会降低到旧CPU的成本; 对于更长的浮动格式,您需要更多时间;例如对于64位,你需要2倍的时间而不是32位;但与64位相比,80位是便宜的。

此外,较新的CPU具有与标量(x87)相同速度的向量运算(SSE,SSE2,AVX)。矢量具有2-4个相同类型的数据。如果您可以将循环对齐以使用相同的操作在多个FP值上工作,那么您将从CPU获得更多性能。

答案 1 :(得分:5)

如果平方根函数没有在特殊硬件或软件中实现,大多数库函数将使用牛顿方法计算它,该方法以二次方式收敛。

Newton的方法是一种迭代方法:您进行初步猜测,计算试验结果,并将其用于下一次猜测。你会重复,直到你认为你的结果“足够接近”。碰巧你可以用平方根来证明你需要多少次迭代。每次循环都会得到另外两位数的精度,因此大多数实现将在8-9个周期内收敛到双精度的精度限制。

如果你仔细阅读this,你会发现迭代牛顿的方法是每次迭代进行两次减法,一次乘法和一次除法。

答案 2 :(得分:2)

作为一般经验法则:浮点除法和平方根都被视为慢速运算(与加法或乘法等快速运算相比)。与分区相比,平方根可以预期大致相同的速度或稍慢(即,性能降低约1x-2x)。例如。在Pentium Pro

  

分区和平方根的潜伏期分别为18到36和29到69个循环

要获得更准确的答案,您需要深入了解您的平台的架构手册或执行基准测试。

注意:许多现代平台也提供反平方根,其速度与sqrt大致相同,但通常更有用(例如,通过使用invsqrt,您可以计算sqrt和div,每个都有一个乘法)。