Вперед: 3.2.3. Разделение работы, параллельные секции
Назад: 3.2.1. Выделение параллельной области
К содержанию: Оглавление


3.2.2. Разделение работы, параллельные циклы

Директива для распределения итераций цикла между нитями:

C/C++:

#pragma omp for [ ключ [ ключ ] ... ] new-line
Цикл for

Fortran:

!$OMP DO [ ключ [ [ , ] ключ ] ... ]
Цикл DO
[ !$OMP END DO [ nowait ] ]

В Фортране директива END DO должна следовать непосредственно за строкой окончания оператора цикла DO. В языке Си директива применяется к блоку, находящемуся внутри оператора цикла for.

В список допустимых ключей входят все ключи директивы PARALLEL. Это позволяет объединять инструкции PARALLEL/END PARALLEL и DO/END DO в пару PARALLEL DO/END PARALLEL DO (parallel for в языках C/C++).

Помимо ключей общих с оператором PARALLEL, имеются ключи специфические для оператора for/DO:

SCHEDULE(тип[,m]) - указывает, каким образом итерации цикла будут распределены между нитями группы. В качестве параметра "тип" можно указать следующие значения:

STATIC - блочно-циклическое распределение итераций блоками размера m. Если m не определено, то размер блока определяется делением числа итераций на число нитей. Таким образом, каждой нити достается один блок. В случае, если число итераций не делиться нацело на число потоков, то компилятор сам распределит остаток между нитями.

DYNAMIC - динамическое распределение итераций с фиксированным размером блока m: сначала все нити получают порции из m итераций, а затем каждая нить, заканчивающая свою работу, получает следующую порцию из m итераций. По умолчанию m = 1.

GUIDED - динамическое распределение итераций блоками уменьшающегося размера; аналогично распределению DYNAMIC, но размер выделяемых блоков все время уменьшается, что в ряде случаев позволяет аккуратнее сбалансировать загрузку нитей. При управляемом планировании число итераций, выполняемых каждым потоком, определяется по следующей формуле:

число_выполняемых_потоком_итераций=
max(число_нераспределенных_итераций/число_нитей,m)
Параметр m определяет минимальный размер блока. По умолчанию m = 1.

RUNTIME - способ распределения итераций цикла выбирается во время работы программы в зависимости от значения переменной OMP_SCHEDULE. Для этого типа распределения параметр m не задается.

AUTO - способ распределения итераций выбирается компилятором или средой исполнения. Параметр m не задается.

LASTPRIVATE (список) - список переменных, которые по окончании параллельного блока должны быть сохранены в базовых переменных. Сохраняются значения с последнего шага цикла.

ORDERED - позволяет задавать внутри тела цикла директивы ORDERED, которые упорядочивают последовательность выполнения шагов цикла.

COLLAPSE(n) - Указывает, сколько вложенных циклов должны образовать единое пространство итераций, которое делится между нитями в соответствии с ключом SCHEDULE.

NOWAIT - директива отменяет необходимость барьерной синхронизации нитей в конце параллельного цикла.

Пример программы с распределением итераций цикла между нитями:

Программа for.c

 #include <stdio.h>
 #include <stdlib.h>
#define TRUE 1
int main()
{
 int i, n = 18;
omp_set_num_threads(4);
/* Функция omp_set_num_threads задает число нитей в параллельном регионе */
#pragma omp parallel default(none) shared(n) private(i)
{
  #pragma omp for schedule(static)
  for (i=0; i<n; i++)
   printf("Нить %d исполняет %d итерацию\n",
   omp_get_thread_num(),i);
/* Функция omp_get_thread_num() определяет номер вызвавшей ее нити */
}
return 0;
}

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

   program do
   integer i,n,TID, omp_get_thread_num

   n = 18
   call omp_set_num_threads(4)
C Функция omp_set_num_threads задает число нитей в 
C параллельном регионе
!$OMP PARALLEL default(none) shared(n) private(i,TID)
!$OMP DO schedule(static)
   do i = 1, n
   TID = omp_get_thread_num()
C Функция omp_get_thread_num() определяет номер 
C вызвавшей ее нити.
   print *, 'Thread = ', TID, ' doing', i, 'iteration'
   end do
!$OMP END DO
!$OMP END PARALLEL
   End
 


Вперед: 3.2.3. Разделение работы, параллельные секции
Назад: 3.2.1. Выделение параллельной области
К содержанию: Оглавление