\subsection{Реализация в DVM-системе}

Как описывалось во введении, распараллеливание в модели DVM происходит при помощи специальных директив. При привычном распараллеливании с распределением данных, в основном, используются следующие директивы:

\begin{itemize}
    \item \texttt{DISTRIBUTE} -- предназначена для распределения элементов массивов по узлам;
    
    \item \texttt{ALIGN} -- отображает элементы нескольких массивов на заданный распределённый массив и распределяет их на соответствующие узлы;

    \item \texttt{REGION} -- определяет область кода, которую следует выполнять параллельно;

    \item \texttt{PARALLEL ... ON} -- определяет цикл, витки которого следует выполнять параллельно, при этом задавая отображение пространства витков цикла на распределённый массив.
\end{itemize}

При этом директива \texttt{PARALLEL ... ON} может включать в себя также произвольное количество следующих клауз:

\begin{itemize}
    \item \texttt{PRIVATE(...)} -- задаёт список приватных переменных;
    
    \item \texttt{REDUCTION(OP(...))} -- задаёт список редукционных переменных с редукционной операцией \texttt{OP};

    \item \texttt{ACROSS(array(}$l_1:r_1$\texttt{, ... ,} $l_n:r_n$\texttt{))} -- задаёт зависимость по данным для $n$-мерного массива \texttt{array}, где $l_k$ и $r_k$ это размеры зависимости для $k$-го измерения \cite[стр.~16]{dvm-doc};
    
    \item \texttt{SHADOW\_RENEW(...)}, \texttt{SHADOW\_COMPUTE(...)} и \texttt{REMOTE\_ACCESS(...)} -- клаузы доступа к удалённым данным (см. \cite{dvm-doc}).
\end{itemize}

Рассмотрим пример распараллеленного в модели DVM гнезда циклов (см. Листинг \ref{lst:dvmh-hello-world}). Здесь происходит отображение элементов массива B на элементы массива A, распределение массива A и распараллеливание гнезда циклов. При запуске на кластере каждый узел получит непрерывные и примерно равные секции массива A, точно такие же секции массива B и соответствующие этим секциям итерации цикла.

\pagebreak

\begin{lstlisting}[style=FORT,caption={
Пример распараллеленного в модели DVM гнезда циклов.
},label={lst:dvmh-hello-world}]
!DVM$ DISTRIBUTE (BLOCK,BLOCK) :: A
!DVM$ ALIGN B(I,J) WITH A(I,J)

!DVM$ REGION
!DVM$ PARALLEL (I,J) ON A(I,J), REDUCTION (MAX(EPS))
    DO I = 1, N
        DO J = 1, N
            EPS = MAX(EPS, ABS(B(I,J) - A(I,J)))
            A(I, J) = B(I, J)
        END DO
    END DO
!DVM$ END REGION
\end{lstlisting}

Чтобы дать пользователю возможность распараллеливать программы на общую память, в синтаксис языка модели DVMH была добавлена новая форма директивы \texttt{PARALLEL} для распараллеливания без распределения данных.

Новый вариант директивы \texttt{PARALLEL} отличается от исходного тем, что в ней отсутствует клауза \texttt{ON}. При использовании таких директив не надо указывать распределённые массивы при отображении витков параллельных циклов. Сами директивы распределения данных также не нужны в таких программах. Более того, в таких директивах \texttt{PARALLEL} не должны присутствовать клаузы доступа к удалённым данным, такие как \texttt{SHADOW\_RENEW}, \texttt{SHADOW\_COMPUTE} и \texttt{REMOTE\_ACCESS}.

В таком варианте директивы \texttt{PARALLEL} может присутствовать клауза \texttt{TIE}, сопоставляющая итерации цикла с массивом. Она используется в DVM-системе для улучшения производительности выходного исполняемого кода.

\pagebreak

\begin{lstlisting}[style=FORT,caption={
Пример распараллеливания гнезда циклов на общую память.
}]
!DVM$ REGION
!DVM$ PARALLEL (I,J), REDUCTION (MAX(EPS)), TIE(A(I, J), B(I, J))
    DO I = 1, N
        DO J = 1, N
            EPS = MAX(EPS, ABS(B(I,J) - A(I,J)))
            A(I, J) = B(I, J)
        END DO
    END DO
!DVM$ END REGION
\end{lstlisting}
