Сравнение Fortran/OpenMP на 2 платформах (компиляторы GCC и PGI). Неожиданные сроки исполнения

Я скомпилировал (с помощью компиляторов GCC и PGI) и запустил небольшую программу на Fortran/OpenMP на двух разных платформах (на основе Haswell и Skylake), просто чтобы почувствовать разницу в производительности. Я не знаю, как интерпретировать результаты - они для меня загадка.

Вот небольшая программа (взята с сайта разработчика Nvidia и немного адаптирована).

PROGRAM main

use, intrinsic :: iso_fortran_env, only: sp=>real32, dp=>real64
use, intrinsic :: omp_lib

implicit none

real(dp), parameter :: tol   = 1.0d-6
integer, parameter :: iter_max = 1000

real(dp), allocatable :: A(:,:), Anew(:,:)
real(dp) :: error
real(sp) :: cpu_t0, cpu_t1
integer :: it0, it1, sys_clock_rate, iter, i, j
integer :: N, M
character(len=8) :: arg

call get_command_argument(1, arg)
read(arg, *) N   !!! N = 8192 provided from command line

call get_command_argument(2, arg)
read(arg, *) M   !!! M = 8192 provided from command line

allocate( A(N,M), Anew(N,M) )

A(1,:) = 1
A(2:N,:) = 0

Anew(1,:) = 1
Anew(2:N,:) = 0

iter = 0
error = 1

call cpu_time(cpu_t0)
call system_clock(it0)

do while ( (error > tol) .and. (iter < iter_max) )

    error = 0

    !$omp parallel do reduction(max: error) private(i)
    do j = 2, M-1
        do i = 2, N-1
            Anew(i,j) = (A(i+1,j)+A(i-1,j)+A(i,j-1)+A(i,j+1)) / 4
            error = max(error, abs(Anew(i,j)-A(i,j)))
        end do
    end do
    !$omp end parallel do

    !$omp parallel do private(i)
    do j = 2, M-1
        do i = 2, N-1
            A(i,j) = Anew(i,j)
        end do
    end do
    !$omp end parallel do

    iter = iter + 1

end do

call cpu_time(cpu_t1)
call system_clock(it1, sys_clock_rate)

write(*,'(a,f8.3,a)') "...cpu time :", cpu_t1-cpu_t0, " s"
write(*,'(a,f8.3,a)') "...wall time:", real(it1 it0)/real(sys_clock_rate), " s"

END PROGRAM

Две платформы, которые я использовал:

  • Intel i7-4770 @ 3,40 ГГц (Haswell), 32 ГБ ОЗУ / Ubuntu 16.04.2 LTS
  • Intel i7-6700 @ 3,40 ГГц (Skylake), 32 ГБ ОЗУ / Linux Mint 18.1 (~ Ubuntu 16.04)

На каждой платформе я скомпилировал программу Fortran с

  • GCC Gfortran 6.2.0
  • PGI pgfortran 16.10 Community Edition

Я, очевидно, скомпилировал программу независимо на каждой платформе (я только переместил файл.f90; я не переместил никакой двоичный файл)

Я запускал 5 раз каждый из 4 исполняемых файлов (по 2 на каждую платформу), собирая время стен, измеренное в секундах (как распечатано программой). (Ну, я провёл весь тест несколько раз, и время, показанное ниже, определенно показательно)

  1. Последовательное исполнение. Программа составлена ​​из:

    • gfortran - быстрый main.f90 -o gcc-seq
    • pgfortran -fast main.f90 -o pgi-seq

    Время (лучшее из 5):

    • Haswell> gcc-seq: 150.955, pgi-seq: 165.973
    • Skylake> gcc-seq: 277.400, pgi-seq: 121.794
  2. Многопоточное исполнение (8 потоков). Программа составлена ​​из:

    • gfortran -Ofast -fopenmp main.f90 -o gcc-omp
    • pgfortran -fast -mp = allcores main.f90 -o pgi-omp

    Время (лучшее из 5):

    • Haswell> gcc-omp: 153.819, pgi-omp: 151.459
    • Skylake> gcc-omp: 113.497, pgi-omp: 107.863

При компиляции с OpenMP я проверял число потоков в параллельных регионах с помощью omp_get_num_threads(), и на самом деле всегда есть 8 потоков, как и ожидалось.

Есть несколько вещей, которые я не понимаю:

  • Использование компилятора GCC: почему в Skylake OpenMP имеет существенное преимущество (277 против 113 с), а в Haswell - вообще нет? (150 против 153 с) Что происходит на Haswell?
  • Использование компилятора PGI: почему OpenMP имеет такое небольшое преимущество (если таковое имеется) на обеих платформах?
  • Сосредоточив внимание на последовательных прогонах, почему существуют такие огромные различия во времени выполнения между Haswell и Skylake (особенно, когда программа компилируется с GCC)? Почему эта разница все еще так актуальна - но с ролью Хэсвелла и Скайлэйк поменялись местами! - когда включен OpenMP?
  • Кроме того, когда OpenMP включен и используется GCC, время процессора всегда намного больше времени стены (как я и ожидал), но когда используется PGI, время процессора и стены всегда одинаково, также тогда программа использовала несколько потоки.

Как я могу иметь какой-то смысл из этих результатов?

0 ответов

Другие вопросы по тегам