Конструкция «Параллельный регион» (parallel)

Самая важная и распространенная директива в OpenMP.

Назначение:

  • Cоздает параллельный регион для следующего за ней структурированного блока.

Формат:

#pragma omp parallel [clause...] newline if (scalar_expression) private (list) shared (list) default (shared | none) firstprivate (list) reduction (operator: list) copyin (list) num_threads (integer-expression) structured_block

Особенности:

  • Когда основной (последовательный) поток достигает директивы, он порождает набор нитей и становится основной нитью в этом наборе, которой присваивается индекс 0.
  • Начиная с начала региона, код дублируется, и все нити выполняют один и тот же код.
  • В конце секции предполагается барьер синхронизации. После выхода из региона мастер продолжает работу.

Ограничения:

  • Запрещены любые переходы в/из параллельного региона

Директива сообщает компилятору, что структурированный блок кода должен быть выполнен параллельно, в нескольких потоках-нитях.

Процесс, выполнивший данную директиву (нить-мастер), всегда получает номер 0.

Каждый поток будет выполнять один и тот же поток команд, но не один и тот же набор команд — все зависит от операторов, управляющих логикой программы, таких как if-else.

Необходимость порождения нитей и параллельного исполнения кода параллельной секции пользователь может определять динамически с помощью дополнительной опции if.

#pragma omp parallel if ( <условие> )

Если <условие> не выполнено, то директива не срабатывает и продолжается обработка программы в прежнем режиме.

Параметр num_threads указывает на число создаваемых нитей, участвующих в параллельной обработке. По умолчанию число нитей равно числу логических процессоров на машине.

Для распределения работы между нитями OpenMP дает возможность программировать на самом низком уровне, распределяя работу с помощью функций omp_get_thread_num() и omp_get_num_threads(), возвращающих номер нити и общее количество порожденных нитей соответственно. Например, если написать фрагмент вида:

if(omp_get_thread_num() == 3)

{

< код для нити с номером 3 >

}

else

{

< код для всех остальных нитей >

}

то часть программы между директивами if:else будет выполнена только нитью с номером 3, а оставшаяся часть - всеми остальными. Как и прежде, этот код будет выполнен всеми нитями, однако функция omp_get_thread_num() возвратит значение 3 только для нити с номером 3, поэтому и выполнение данного участка кода для третьей нити и всех остальных будет идти по-разному.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: