random_number 子程序运行时间比较 ifort 与 gfortran

问题描述

我写了这段代码

program random
    implicit none

    integer :: i,j,limit
    real(8) :: r,max_val
    real(8) :: start,finish

    max_val = 0.d0
    limit = 10000

    call cpu_TIME(start)
    do i=1,limit
        do j=1,limit
            call random_number(r)
            max_val = max(max_val,r)
        end do
    end do
    call cpu_TIME(finish)
    print *,max_val
    print '("Time = ",f6.3," seconds.")',finish-start
end program random

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

ifort *.f90 -O3 -no-vec -o intel.out

gfortran *.f90 -O3 -fno-tree-vectorize -o gnu.out

输出是:

GNU:

0.9999999155521957
Time = 0.928 seconds.

情报:

0.999999968800691 (same for every run btw)
Time = 1.989 seconds.

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

为什么 gfortran 比 ifort 快,我怎样才能让 ifort 像 gfortran 一样快?

解决方法

不同的编译器都有自己的库,其中包含其内在函数和子例程的实现。它们的性能会有所不同,结果也可能会有所不同。 Gfortran 将 GLIBC 库用于许多通用的内部函数,而 libgfortran 库用于许多 Fortran 特定的内部函数。英特尔编译器带有自己的运行时库套件。

值得注意的是,the Fortran standard gives no guarantees 关于用于 random_number() 的伪随机生成器的质量。即使是这样,代码中的实际实现也总是会有所不同,因此实际性能也会有所不同。

有许多可用的外部伪随机数生成器库。有的快,有的慢。一些更健壮,一些未能通过某些随机性测试。 (有时确实很重要,有时则不重要)。有些在一次调用中提供更多的随机位,有些在一次调用中提供更少的随机位。如果您在所有编译器中都需要生成器的某些特定属性,最好使用外部库。