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


3.2. Директивы OpenMP

Выделение параллельной области

C/C++:

#pragma omp parallel [ ключ [ ключ ] ... ] new-line
structured-block

Fortran:

!$OMP PARALLEL [ ключ [ [ , ] ключ ] ... ]
Фрагмент программы
!$OMP END PARALLEL

Директивы PARALLEL/END PARALLEL должны находиться внутри одной процедуры

В языках C/C++ не требуется завершающего оператора, поскольку эти языки поддерживают блочную структуру и директива относится к блоку.

Ключи определяют типы переменных и их поведение при входе в параллельную область и выходе из нее.
Возможные ключи:

IF (условие) - Выполнение параллельной области по условию. Вхождение в параллельную область происходит только, если условие принимает значение <Истина>.

SHARED (список) - Явным образом определяет список переменных, которые должны быть общими для всех нитей параллельной области.

PRIVATE (список) - Определяет список переменных, которые должны быть локальными для каждой нити. При входе в параллельную область для каждой нити создается отдельный экземпляр переменной, который не имеет никакой связи с оригинальной переменной вне параллельной области. Изменение значения локальной переменной какой-либо нитью ни как не влияет на значения этой переменной в других нитях.

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

DEFAULT (PRIVATE|FIRSPRIVATE|SHARED|NONE) - Всем переменным в параллельной области, которым явно не назначен класс, будет назначен класс PRIVATE, FIRSTPRIVATE или SHARED соответственно. Значение NONE указывает, что значение по умолчанию ни каким переменным не устанавливается. В языках C/C++ допустимы только значения SHARED или NONE.

REDUCTION(операция: список) - Операция редукции производится над копиями переменных во всех нитях, и результат присваивается базовой переменной.

Допустимые операции:

C/C++:
+, *, -, &, ^, |, &&, or, ||

Fortran:
+, *, -, .and., .or., .eqv., .neqv.,max, min, iand, ior, ieor

COPYIN (список) - Применяется к глобальным переменным в С/С++ и COMMON-блокам в Фортране, которые помечены как THREADPRIVATE. При входе в параллельную область приватные копии этих данных инициируются оригинальными значениями.

NUM_THREADS (целочисленное выражение) задание количества нитей, порождаемых в параллельной области. По умолчанию выбирается последнее значение, установленное с помощью функции omp_set_num_threads(), или значение переменной OMP_NUM_THREADS.

Приведем пример простейшей параллельной программы на языках Си и Фортран.

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

 #include <omp.h> 
 main () {
 int nthreads, tid;
 /* Генерация ансамбля нитей */
 #pragma omp parallel private(tid)
 {
 /* получение и печать идентификаторов нитей */
 tid = omp_get_thread_num();
 printf("Hello World from thread = %d\n", tid);
 /* определение мастер-нитью общего числа нитей */
 if (tid == 0) 
  {
  nthreads = omp_get_num_threads();
  printf("Number of threads = %d\n", nthreads);
  }
 } /* Закрытие всех нитей, кроме мастер-нити */
 }

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

    PROGRAM PARALLEL
    INTEGER NTHREADS, TID, OMP_GET_NUM_THREADS,
   +  OMP_GET_THREAD_NUM

C   Генерация ансамбля нитей
!$OMP PARALLEL PRIVATE(TID)
C   получение и печать идентификаторов нитей
   TID = OMP_GET_THREAD_NUM()
   PRINT *, 'Hello World from thread = ', TID
C   определение мастер-нитью общего числа нитей 
   IF (TID .EQ. 0) THEN
    NTHREADS = OMP_GET_NUM_THREADS()
    PRINT *, 'Number of threads = ', NTHREADS
   END IF
C   Закрытие всех нитей, кроме мастер-нити
!$OMP END PARALLEL
    END
 

Создание параллельных областей само по себе не приводит к ускорению работы программы, Каждая нить будет выполнять одну и ту же последовательность команд. Для распределения работы между нитями служат специальные директивы.

В OpenMP имеется несколько возможностей по распределению вычислений между нитями.



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