Вперед: 1.4.2.4. Язык параллельного программирования HPF
Назад: 1.4.2.2. Коммуникационный интерфейс MPI
К содержанию: Оглавление


1.4.2.3. Совместное использование MPI и OpenMP

Производительность вычислительного кластера определяется двумя факторами: количеством вычислительных узлов и производительностью каждого вычислительного узла. Идея увеличения производительности кластера за счет наращивания производительности вычислительных узлов выглядит весьма привлекательной и используется уже давно. В самом деле, использование двухпроцессорных узлов вместо однопроцессорных позволяет вдвое увеличить общую производительность вычислительной системы без какого-либо существенного усложнения технических решений. Особенно массовый характер этот подход принял после появления многоядерных процессоров. На сегодняшний день стандартной является конфигурация вычислительного узла с двумя 4-х ядерными процессорами. А появились процессоры и с 6-ю и с 10-ю ядрами. Без сомнения, они найдут широкое применение при создании вычислительных кластеров. В связи с этим остро возник вопрос - как наиболее эффективно использовать такие вычислительные системы? Достаточно очевидно, что если на узле 8 ядер, то вряд ли целесообразно запускать на нем 8 независимых процессов. Во-первых, резко возрастет число конфликтов по шине памяти. А во-вторых, велик риск, что операционная система уйдет в <свопинг>, если памяти на узле не хватит для постоянного размещения в ней наиболее активно используемых страниц всех процессов. Наиболее разумным решением представляется запуск на каждом узле одного многонитевого процесса, который бы смог задействовать всю вычислительную мощь узла. Такая схема предполагает совместное использование двух технологий для распараллеливания программы: MPI - для распараллеливания между узлами, и OpenMP - для распараллеливания внутри узлов.

В нашем случае, ввиду простоты программы, эта идея реализуется достаточно легко. Приведем текст соответствующей программы.

Программа pi_mix.f

program pi_mpi
   include 'mpif.h'
   integer n, i
   double precision d, s, x, pi, temp
   integer myid, numprocs, ierr, status(3)
   integer sumtag, sizetag
   call MPI_INIT(ierr)
   call MPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)
   call MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)
   sizetag = 10
   sumtag = 17
   if (myid .eq. 0) then
    write(*,*) 'n?'
    read(*,*) n
   endif
   call MPI_BCAST(n,1,MPI_INTEGER,0,
   $   MPI_COMM_WORLD,ierr) 
   d = 1.0/n
   s = 0.0
!$OMP PARALLEL PRIVATE(x), SHARED(d)
!$OMP& REDUCTION(+: s)
!$OMP DO
   do i = myid+1, n, numprocs
     x = (i-0.5)*d
     s = s+4.0/(1.0+x*x)
   enddo
!$OMP END DO
!$OMP END PARALLEL
   pi = d*s
   call MPI_REDUCE(pi,temp,1,MPI_DOUBLE_PRECISION,
   $   MPI_SUM,master,MPI_COMM_WORLD,ierr) 
   pi = temp
   if (myid .eq. 0) then
    write(*, 100) pi
 100  format(' pi = ', f20.15)
   endif
   call MPI_FINALIZE(ierr)
   end

В этой MPI-программе с помощью OpenMP распараллелено вычисление частичных сумм на каждом многоядерном узле. Читателю предлагается в качестве упражнения написать такую программу на языке Си.

Интересно отметить, что при тестировании производительности вычислительного узла, содержащего два 4-х ядерных процессора, с помощью теста HPL [17] оказалось, что максимальная производительность достигается тогда, когда на узле запускается два 4-х нитевых процесса, т.е. когда структура программы наилучшим образом соответствует архитектуре узла. Результаты тестирования для различных сочетаний числа процессов и числа нитей в каждом процессе представлены в Таблице 1.1

Табл. 1.1. Тестирование вычислительного узла, содержащего два 4-х ядерных процессора Intel Xeon(R) E5345 @ 2.33GHz на программе HPL.

Размерность решаемой системы уравнений N = 40000

proc х threads 1 x 1 1 x 8 2 x 4 4 x 2 8 x 1 8 x 1*
время решения(cek.) 5173 751 729 751 747 689
производительность(Gflops) 8.25 56.80 58.50 56.79 57.11 61.87

* В расчете использовано 8 узлов, по одному процессу на узле.

Здесь в первом столбце представлена производительность одного процессорного ядра. В столбцах 2 - 5 производительность узла в целом, при различных сочетаниях количества процессов и нитей в вычислительном узле. Последний столбец иллюстрирует масштабируемость программы по узлам кластера. Из таблицы видно, что полная производительность вычислительного узла на программе HPL примерно в 7 раз выше, чем производительность одного ядра, и она слабо зависит от сочетания числа процессов и нитей в узле. К сожалению, на реальных программах, обрабатывающих большие массивы данных, масштабируемость внутри узла оказывается значительно хуже, и кроме того, она практически всегда хуже, чем масштабируемость по вычислительным узлам, при условии, что используется скоростная коммуникационная сеть Infiniband.



Вперед: 1.4.2.4. Язык параллельного программирования HPF
Назад: 1.4.2.2. Коммуникационный интерфейс MPI
К содержанию: Оглавление