Performance ifort-ipo标志奇怪的行为

Performance ifort-ipo标志奇怪的行为,performance,compiler-construction,fortran,flags,Performance,Compiler Construction,Fortran,Flags,我有以下用于测试“英特尔mkl DAXPY”例程的代码 program test implicit none integer, parameter :: n = 50000000 integer, parameter :: nloop = 100 real(8), dimension(:), allocatable :: a, b integer start_t, end_t, rate, i allocate(a(n)) allocate

我有以下用于测试“英特尔mkl DAXPY”例程的代码

program test
    implicit none
    integer, parameter :: n = 50000000
    integer, parameter :: nloop = 100
    real(8), dimension(:), allocatable :: a, b
    integer start_t, end_t, rate, i
    allocate(a(n))
    allocate(b(n))

    a = 1.0d0
    b = 2.0d0
    call system_clock(start_t, rate)
    do i = 1, nloop
        call sumArray(a, b, a, 3.0d0, n)
    end do
    call system_clock(end_t)
    print *, sum(a)
    print *, "sumArray time: ", real(end_t-start_t)/real(rate)

    a = 1.0d0
    b = 2.0d0
    call system_clock(start_t, rate)
    do i = 1, nloop
        call daxpy(n, 3.0d0, b, 1, a, 1)
    end do
    call system_clock(end_t)
    print *, sum(a)
    print *, "daxpy time: ", real(end_t-start_t)/real(rate)

    a = 1.0d0
    b = 2.0d0
    call system_clock(start_t, rate)
    do i = 1, nloop
        a = a + 3.0d0*b
    end do
    call system_clock(end_t)
    print *, sum(a)
    print *, "a + 3*b time: ", real(end_t-start_t)/real(rate)
end program test

subroutine sumArray(x, y, z, alfa, n)
    implicit none
    integer n, i
    real(8) x(n), y(n), z(n), alfa
    !$OMP PARALLEL DO
    do i = 1, n
        z(i) = x(i) + alfa*y(i)
    end do
    !$OMP END PARALLEL DO
end subroutine sumArray
这里,sumArray是一个带有openmp的手写子例程,其功能类似于DAXPY。 当我使用
ifort test.f90-o test-O3-openmp-mkl
编译代码时,结果大致如下:

但是,当我使用
ifort test.f90-o test-O3-openmp-mkl-ipo编译它时,
a+3*b
的结果会发生显著变化:

sumArray time: 5.7 sec
daxpy time: 5.7 sec
a + 3*b time: 9.3 sec

那么首先,为什么朴素数组和比mkl好?而
-ipo
与原始数组总和的放缓有什么关系?另外,困扰我的是,当我消除循环时,也就是说,当我只对每个操作计时一次时,时间就像第一种情况除以1000(对于
-sumArray
daxpy
,大约5.7ms,对于
a+3*b
),而不管使用
-ipo
。我的猜测是,循环中的朴素求和允许编译器进一步优化,但
-ipo
标志将此优化搞砸注意:我知道在这种情况下,
-ipo
是无用的,因为它是一个单独的文件。

第三次求和后,您不会使用
a
。编译器完全可以删除求和循环…?实际代码在每个循环后打印求和(a)。我只是为了清楚起见把它去掉了。而且,即使如此,我也不明白为什么——ipo会和这种优化有什么关系——ipo做了更积极的优化。如果您向我们展示了实际的代码,我们可以进一步评论,但是我在最后一个循环之后添加了一个a元素的打印-即使使用-ipo,时间也比之前的循环要长。我无法重现你在这里展示的明显缩短的时间。您可能想打开优化报告(-opt report=3),看看它是否能给您提供线索。我的问题中有一个错误。情况正好相反:当我使用
-ipo
编译时,原始求和速度较慢。我编辑了我的问题。实际代码与这里的代码一样,在每个循环后加上一个
print*,和(a)
。不管怎样,我现在添加了这些行。我没有看到有或没有-ipo的显著区别。如果没有ipo,我得到的是8.54、8.12、10.20倍(四核i7965)。与-ipo,8.55,7.77,10.12。在没有ipo的情况下,你是否一直在第三次循环中获得如此短的时间?
sumArray time: 5.7 sec
daxpy time: 5.7 sec
a + 3*b time: 9.3 sec