Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ pow(x,0.5f)的快速实现是否比快速sqrt(x)快?_C++_C_Performance_Math - Fatal编程技术网

C++ pow(x,0.5f)的快速实现是否比快速sqrt(x)快?

C++ pow(x,0.5f)的快速实现是否比快速sqrt(x)快?,c++,c,performance,math,C++,C,Performance,Math,例如,我想知道pow()的快速实现是否比快速sqrt(x)更快地获得整数的平方根。我们知道 sqrt(x) = pow(x, 0.5f) 我不能自己测试速度,因为我没有找到sqrt的快速实现。 我的问题是:pow(x,0.5f)的快速实现比快速sqrt(x)快吗 编辑:我的意思是双打中的powf-pow。(双倍更具误导性)一般来说,在相同的误差约束条件下,一个更具体的问题可以比一个更一般的问题更优化 因此,您可以采用该算法,并将b替换为常数0.5,现在您有了一个至少与pow()一样快的sqrt

例如,我想知道pow()的快速实现是否比快速sqrt(x)更快地获得整数的平方根。我们知道

sqrt(x) = pow(x, 0.5f)
我不能自己测试速度,因为我没有找到sqrt的快速实现。 我的问题是:pow(x,0.5f)的快速实现比快速sqrt(x)快吗


编辑:我的意思是双打中的powf-pow。(双倍更具误导性)

一般来说,在相同的误差约束条件下,一个更具体的问题可以比一个更一般的问题更优化

因此,您可以采用该算法,并将b替换为常数0.5,现在您有了一个至少与pow()一样快的sqrt()。现在它是常量,编译器(或人工)可以基于此进行优化


请注意,pow()函数是一个近似函数,具有(相对)较大的错误,因此不如大多数库sqrt函数那样精确。如果您将sqrt的实现放宽到相同的近似极限,您确实可以使它至少同样快。

对于C标准库
sqrt
pow
,答案是

首先,如果
pow(x,.5f)
sqrt(x)
的实现快,则指定维护sqrt的工程师将用
pow(x,.5f)
替换实现

其次,商业库中sqrt的实现通常是专门为执行该任务而优化的,通常是由熟悉编写高性能软件、使用汇编语言或接近汇编语言编写以从处理器获得最佳性能的人员进行的

第三,许多处理器都有执行sqrt或协助计算sqrt的指令。(通常,有一条指令用于提供平方根倒数的估计值,还有一条指令用于改进该估计值。)

然而 您链接的代码/您提出的问题是关于使用粗略近似的
pow
尝试粗略近似
sqrt

我将问题中提到的pow近似例程的最终版本转换为C,并在计算
pow(3.5)
时测量它的运行时间。我还测量了系统(MacOSX10.8)pow和sqrt以及of的运行时间(通过一次迭代并在最后乘以参数得到平方根,而不是平方根的倒数)

首先,计算结果:pow近似值返回1.72101。sqrt近似值返回1.73054。系统pow和sqrt返回的正确值为1.73205

在MacPro4,1上以64位模式运行时,pow近似值大约需要6个周期,系统pow需要29个周期,平方根近似值需要10个周期,系统sqrt需要29个周期。这些时间可能包括一些加载参数和存储结果的开销(我使用volatile变量强制编译器不要优化其他无用的循环迭代,以便对它们进行度量)


(这些时间是“有效吞吐量”,实际上是从一个调用开始到另一个调用可以开始的CPU周期数。)

结果在MSVC++2013 64位模式下运行以下代码,完全优化~sqrt()的9倍性能

距离是2619435809228.278300

Pow()经过的时间为18413.000000毫秒

#define LOOP_KNT 249000000  // (SHRT_MAX * 1024)

int main(void)    {
    time_t start = clock();

    double distance = 0, result = 0;
    start = clock();
    for(int i=0; i<LOOP_KNT; i++) {
        result = pow(i, 0.50);
        distance += result;
    }
    printf("\nDistance is %f", distance);
   printf("\nPow() elapsed time was %f milliseconds", (double)clock() - (double)(start));

   distance = 0, result = 0;
   start = clock();
    for(int i=0; i<LOOP_KNT; i++) {
        result = sqrt(i);
        distance += result;
    }
    printf("\nDistance is %f", distance);
    printf("\nSqrt() elapsed time was %f milliseconds", (double)clock() - (double)(start));

   printf("\nHit any key to end program.\n");
   getchar();

   return 0;
}
距离是2619435809228.278300

Sqrt()经过的时间为2002.000000毫秒

#define LOOP_KNT 249000000  // (SHRT_MAX * 1024)

int main(void)    {
    time_t start = clock();

    double distance = 0, result = 0;
    start = clock();
    for(int i=0; i<LOOP_KNT; i++) {
        result = pow(i, 0.50);
        distance += result;
    }
    printf("\nDistance is %f", distance);
   printf("\nPow() elapsed time was %f milliseconds", (double)clock() - (double)(start));

   distance = 0, result = 0;
   start = clock();
    for(int i=0; i<LOOP_KNT; i++) {
        result = sqrt(i);
        distance += result;
    }
    printf("\nDistance is %f", distance);
    printf("\nSqrt() elapsed time was %f milliseconds", (double)clock() - (double)(start));

   printf("\nHit any key to end program.\n");
   getchar();

   return 0;
}
#定义循环_knt249000000/(SHRT_MAX*1024)
内部主(空){
开始时间=时钟();
双距离=0,结果=0;
开始=时钟();

对于(int i=0;iThat实现是一个近似值,这意味着它比使用sqrt有更高的错误,这就是为什么它可以更快。更改为单精度参数和返回类型会改变我下面答案中的数字:pow近似值需要9个周期,而不是6个周期(它被写为在double上操作,因此必须转换类型;可能它可以被重写为float),powf需要16个周期而不是29个周期,sqrt近似需要7个周期而不是10个周期(反向效应,它被写为float,因此类型转换消失),而sqrtf取16而不是29。数字
0.5
可以用IEEE浮点精确表示,因此编译器可以将
pow(x,0.5)
重写为
sqrt(x)
,并允许C库执行
返回sqrt(x)
当第二个参数为0.5时,从内部
pow
查看。我不知道有任何实现可以实现这两种功能,但如果知道其中一种,我不会感到惊讶。我写上述内容是为了在一个典型的库中比较sqrt和pow。但是,问题要求我们将sqrt与pow近似值进行比较。在这种情况下,(非常糟糕)在某些平台上,pow近似可能优于sqrt。但是,请注意,pow近似声称典型错误为5%到12%。典型sqrt实现中的错误通常在.000000000000222%左右。因此,这不是一个公平的比较。确实。我在回答中考虑了这一点,但我将对其进行编辑以使其更清楚……如果是willing为了降低精度,直接近似于
sqrt()
会更快。用错误逼近
sqrt
非常简单。只需对浮点表示的位进行操作,将指数减半,然后对尾数进行廉价的修正……感谢您的回答;但是标准库中的
sqrt
pow
都非常慢。注意:尝试了sa我在我的Cygwin 64位PC上-比率为1.04。
pow()vs sqrt()
@Zaffy,Close只在马蹄铁和手榴弹中计算。25%的错误会使链接方法一文不值。它也是Java的,一开始性能就很差。“这非常紧凑。计算只需要2秒。”