exp 函数运行时间比较 ifort 与 gfortran

nad*_*hmi 3 performance assembly fortran gfortran intel-fortran

我写了这段代码:

program exponent
    implicit none

    real(8) :: sum
    integer(8) :: i
    integer :: limit
    real :: start, end

    sum = 0d0
    limit = 10000000
    call CPU_TIME(start)
    do i=1, limit
        sum = sum + exp(i*1.d0/limit)
    end do
    call CPU_TIME(end)
    print *, sum
    print '("Time = ",f6.3," seconds.")',end-start
end program exponent
Run Code Online (Sandbox Code Playgroud)

我在 CentOS Linux 7 上使用 gfortran 10.1.0 和 ifort 19.1.3.304 编译它:

ifort *.f90 -O3 -o intel.out

gfortran *.f90 -O3 -o gnu.out

输出是:

格努:

17182819.143730670
Time = 0.248 seconds.
Run Code Online (Sandbox Code Playgroud)

英特尔:

17182819.1437313
Time = 0.051 seconds.
Run Code Online (Sandbox Code Playgroud)

当我运行几次时,每次的运行时间几乎相同。

为什么 ifort 比 gfortran 快?如何使 gfortran 运行得和 ifort 一样快?

Jér*_*ard 5

ifort 速度更快,主要是因为它使用自己的优化数学库,称为 SVML(由英特尔编译器提供)。该库通常速度更快,因为它提供了优化的矢量化基元,即使没有-ffastmath. 此外,英特尔编译器倾向于更好地矢量化循环(尤其是像这样的减少)。

您可以在 GodBolt 上看到差异:ifort 版本通过一次处理 2 个数字来矢量化循环,而 gfortran 版本使用较慢的标量指数。

请注意,由于 AVX 指令集,使用-mavx2有助于 ifort 生成更快的代码。使用 AVX-512 指令(如果目标机器上可用)可能会更快。gfortran 可以使用 on GodBolt 对循环进行矢量化-march=native(但奇怪的是不能使用-march=skylakeand -ffast-math)。

  • 奇怪的是,gfortran 只会使用带有“-march=skylake-avx512”(这些云服务器上原生的)的矢量化“exp”,而不是“-march=skylake”。即使 `-mveclibabi=svml` 或 `acml` 也没有帮助。https://sourceware.org/glibc/wiki/libmvec 表示 gcc4.9 应该能够使用“-O1 -fopenmp -ffast-math -lm -mavx2”或“-O1”对“cos()”等 C 函数进行矢量化-ftree-loop-向量化-ffast-math -lm -mavx`。(-O3 包括 -ftree-vectorize) (2认同)