Язык параллельного программирования HPF ( High Performance Fortran )
Copyright Посыпкин М.А. ОБЩЕЕ ОПИСАНИЕ Создан: Ken Kennedy, Geoffrey Fox HPF является расширением FORTRAN90 Парадигма программирования: распределенная память+SPMD Стандартизован (HPF год)
Copyright Посыпкин М.А. ВЕКТОРНЫЕ ОПЕРАЦИИ В FORTRAN 95 REAL, DIMENSION :: A(5, 5) REAL, DIMENSION :: B(5, 5) A(2:4, :) = B(1:5:2, :) AB массивы должны быть конформны !
Copyright Посыпкин М.А. ОПЕРАТОР FORALL FORALL (I = M:N:S, J = K:L) A(I) = B(I + 1, J) B(I, J) = B(I – 1, J) END FORALL FORALL (I = M:N) A(I) = B(I) все выражения в левой части выполняются до выполнения присваивания !
Copyright Посыпкин М.А. СРЕДСТВА ВЫРАЖЕНИЯ ПАРАЛЛЕЛИЗМА Код программы инструментируется директивами !HPF$ … Семантика программы остается прежней Назначение директив: распределение данных распределение работы
Copyright Посыпкин М.А. РЕШЕТКА ПРОЦЕССОРОВ Число процессоров в решетке должно совпадать с числом физических процессоров !HPF$ PROCESSORS :: RUBIK(3, 3, 3) !HPF$ PROCESSORS, DIMENSION(3, 3, 3) :: RUBIK !HPF$ PROCESSORS:: BAR(NUMBER_OF_PROCESSORS())
Copyright Посыпкин М.А. РАСПРЕДЕЛЕНИЕ ДАННЫХ !HPF$ DISTRIBUTE A(BLOCK, BLOCK, CYCLIC) ONTO RUBIK Способы распределения: BLOCK (n) блоками равной (кроме последнего блока) величины, где N – протяженность массива по данной размерности или указанной пользователем, p – протяженность решетки процессоров по данной размерности (без «закручивания» вокруг решетки процессоров) CYCLIC (n) – циклически блоками длины 1 или указанной пользователем длины n * - размерность не распределяется число распределяемых размерностей должно совпадать с числом размерностей массива процессоров
Copyright Посыпкин М.А. !HPF$ PROCESSORS :: PP (2,2)REAL A(6,5) !HPF$ DISTRIBUTE A (BLOCK, BLOCK)ONTO PP !HPF$ DISTRIBUTE A (BLOCK, CYCLIC) ONTO PP
Copyright Посыпкин М.А. «ВЗАИМОВЫРАВНИВАНИЕ» МАССИВОВ !HPF$ ALIGN A(:, :) WITH B(:, :) !HPF$ DISTRIBUTE B(:, :) ONTO P aligneealign target массивы должны быть конформны !
Copyright Посыпкин М.А. ШАБЛОН ВЫРАВНИВАНИЯ REAL, DIMENSION (5, 20) :: A !HPF$ TEMPLATE, DIMENSION (10, 20) :: T !HPF$ ALIGN A( :, : ) WITH T(1:5, : ) !HPF$ DISTRIBUTE T (BLOCK, BLOCK) ONTO P
Copyright Посыпкин М.А. REAL A(4) !HPF$ TEMPLATE T(8) !HPF$ ALIGN A WITH T(1:4) A T !HPF$ ALIGN A WITH T(2:8:2) A T
Copyright Посыпкин М.А. МОДЕЛЬ ВЫПОЛНЕНИЯ HPF-ПРОГРАММЫ «Обычные» циклы выполняются последовательно. Распараллеливанию подвергаются векторные операции, оператор FORALL и циклы, помеченные директивой INDEPENDENT. Есть возможность явно указывать распределение работы с помощью директивы ON.
Copyright Посыпкин М.А. ! numerical integration to calculate pi program calc_pi integer i, n double precision w, gsuM double precision, allocatable :: v(:) !hpf$ distribute v(block) integer tickstart, tickstop, tickrate integer np real time, mflops print *, 'Input number of stripes : ' read *, n call system_clock (tickstart, tickrate) w = 1.0 / n
Copyright Посыпкин М.А. allocate (v(n)) forall (i=1:n) v(i) = i v = (v )* w v = 4.0 / (1.0 + v * v) gsum = sum (v) call system_clock (tickstop) np = number_of_processors () time = float (tickstop - tickstart) / float(tickrate) mflops = 9 * n / ( * time) print *, 'pi ist approximated with ', gsum *w print *, 'time = ', time, ' seconds' print *, 'mflops = ', mflops, ' on ', np, ' processors' print *, 'mflops = ', mflops/np, ' for one processor' deallocate (v) end
Copyright Посыпкин М.А. Директива INDEPENDENT Директива INDEPENDENT сообщает транслятору, что порядок выполнения итераций последующего цикла не является существенным и их можно выполнять параллельно. !HPF$ INDEPENDENT DO I = 1,N A(I) = B(I) + C(I + 1) ENDDO
Copyright Посыпкин М.А. ОПЦИИ ДЛЯ INDEPENDENT !HPF$ INDEPENDENT NEW(X), REDUCTION(Y) NEW – переменная «своя» для каждой итерации цикла REDUCTION – переменная изменяется редуктивным образом в теле цикла (операция определяется транслятором из текста программы): !HPF$ INDEPENDENT, REDUCTION(X) DO I=1:100 X(P(I)) = X(P(I)) + V ENDDO
Copyright Посыпкин М.А. ПРИМЕР РЕДУКЦИИ REAL Z Z = 5. !HPF$ INDEPENDENT, REDUCTION(Z) DO Z = Z + 1 ENDDO Результат: Z = 5 + ( )
Copyright Посыпкин М.А. ! numerical integration to calculate pi program calc_pi integer i, n double precision w, gsuM double precision v integer tickstart, tickstop, tickrate integer np real time, mflops print *, 'Input number of stripes : read *, n call system_clock (tickstart, tickrate) w = 1.0 / n gsum = 0.0d0
Copyright Посыпкин М.А. !hpf$ independent, new (v), reduction (gsum) do i = 1, n v = (i - 0.5d0 ) * w v = 4.0d0 / (1.0d0 + v * v) gsum = gsum + v end do call system_clock (tickstop) np = number_of_processors () time = float (tickstop - tickstart) / float(tickrate) mflops = 9 * n / ( * time) print *, 'pi ist approximated with ', gsum *w print *, 'flop = ', 9 * dble(n) print *, 'time = ', time, ' seconds print *, 'mflops = ', mflops, ' on ', np, ' processors print *, 'mflops = ', mflops/np, ' for one processor end