首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Fortran计算实际*4的平方根的速度与ints的相加一样快?

Fortran计算实际*4的平方根的速度与ints的相加一样快?
EN

Stack Overflow用户
提问于 2016-06-24 10:24:28
回答 3查看 1.2K关注 0票数 4

剧透程序:测试程序没有对结果做任何事情,所以优化编译器删除了循环的内容,因此每次运行都不需要同样的时间。无论如何,我会让问题和答案保留下来,以防有人(我?)同样的错误(再次.)。

原始文章:,我想测试与简单的加法相比,计算平方根的速度要慢多少,并编写了下面的小程序。我得到的结果是,在这种情况下,大约需要同样的时间,0.3秒。这里发生什么事情?

代码语言:javascript
复制
program sqtest
implicit none
real r, s
integer i,j,n, sq, t

sq=11
n=100000000
r=1.11

if (sq==1) then
 do i = 1,n
  s = sqrt(float(i)*r)
 enddo
 write(*,*) "squareroot"
else
 do j = 1,n
  t = j+4
 enddo
 write(*,*) "plus"
endif


end program

sq=1放置为使用平方根。平方根循环aso进行乘法和从intfloat的转换。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-24 14:21:03

在进行这样的测试时,有很多事情要考虑。首先,你必须清楚地定义你在比较什么。对于这样简单的测试,您还应该禁用优化,大多数主要编译器都接受选项-O0来禁用优化。否则,编译器会发现您没有对计算值执行任何操作,甚至没有运行您的循环,因为它是无用的。

为了缩短它的长度,我修改了你的程序,使之

代码语言:javascript
复制
program sqtest
implicit none
real r0, r1, r2, s
integer i,n
real :: start, finish


    n=10**9
    call random_number(r0)
    call random_number(r1)
    call random_number(r2)


    call cpu_time(start)
    do i = 1,n
        s = sqrt(r0)
    enddo
    call cpu_time(finish)
    print '("SQRT:      Time = ",f6.3," seconds.")',finish-start

    call cpu_time(start)
    do i = 1,n
        s = r1+r2
    enddo
    call cpu_time(finish)
    print '("Addtition: Time = ",f6.3," seconds.")',finish-start

end program

它给出了我的系统的以下结果:

代码语言:javascript
复制
ifort 13, n = 10^8
SQRT:      Time =  0.378 seconds
Addtition: Time =  0.202 seconds

ifort 13, n = 10^9
SQRT:      Time =  3.460 seconds
Addtition: Time =  1.857 seconds

gfortran (GCC) 4.9, n = 10^8
SQRT:      Time =  0.385 seconds
Addtition: Time =  0.191 seconds

gfortran (GCC) 4.9, n = 10^9
SQRT:      Time =  3.529 seconds
Addtition: Time =  1.733 seconds

pgf90 14, n = 10^8
SQRT:      Time =  0.380 seconds
Addtition: Time =  0.058 seconds

pgf90 14, n = 10^9
SQRT:      Time =  3.438 seconds
Addtition: Time =  0.520 sec

您将注意到,我在代码中调用CPU时间。要使数字有意义,您应该多次运行每一种情况,并计算时间平均值或选择最小值。最小值是接近系统在最优条件下所能达到的目标。您还将看到结果依赖于编译器。pgf90显然给出了更好的加法结果。我从平方根中删除了float(i)*。gfortran和pgf90的执行速度非常快(~ 2.6秒,n= 10^9),而ifort执行得非常慢(n=10^9为7.3秒)。这意味着gfortran和pgf90在那里选择了不同的路径(更快的操作),也许他们做了一些优化,即使我禁用了它?

票数 3
EN

Stack Overflow用户

发布于 2016-06-24 14:17:22

您将在本文档中找到硬件平方根的成本:tables.pdf

可以用不同的方法计算sqrt。一般来说,它是一个迭代过程,只涉及加和乘操作。通常,sqrt被计算为sqrt(x) =x* (1/ sqrt(x) ),因为(1/sqrt(x))可以比sqrt(X)更快地计算。

如果使用Haswell CPU,单个SQRTSS指令的延迟时间为单精度11个周期,双精度16个周期(SQRTSD)。在单精度情况下,与双精度相比,收敛到期望精度所需的迭代次数较少。在同一个CPU上,有一个大约的sqrt (RSQRTSS)版本,延迟为一个周期,所以如果您请求积极的优化,编译器可以选择生成这个指令。

如果您需要多个独立的平方根,如您的示例所示,编译器可以自动将代码向量化。存在向量化变体VSQRTPS,其交互吞吐量为14。在这种情况下,平均为14/8 =每sqrt 1.75个周期。

参考文献:

票数 2
EN

Stack Overflow用户

发布于 2016-06-24 10:30:09

也许您的编译器正在优化代码。你可以用n(例如1e6,1e7,1e8,…,1e10)的不同数量级来测试这一点,看看时间尺度是如何变化的。顺便说一句,您的机器/编译器上允许的整数范围是多少?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38011140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档