Параллельное программирование с использованием OpenMP. Антонов (2009) (Параллельное программирование с использованием OpenMP. Антонов (2009).pdf), страница 8
Описание файла
PDF-файл из архива "Параллельное программирование с использованием OpenMP. Антонов (2009).pdf", который расположен в категории "". Всё это находится в предмете "суперкомпьютерное моделирование и технологии" из 11 семестр (3 семестр магистратуры), которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 8 страницы из PDF
end sections) используется для задания конечного (неитеративного) параллелизма.Си:#pragma omp sections [опция [[,] опция]...]47Фортран:!$omp sections [опция [[,] опция]...]<блок секций>!$omp end sections [nowait]Эта директива определяет набор независимых секций кода, каждая из которых выполняется своей нитью.Возможные опции:private(список) – задаёт список переменных, для которых порожда-ется локальная копия в каждой нити; начальное значение локальныхкопий переменных из списка не определено;firstprivate(список) – задаёт список переменных, для которых по-рождается локальная копия в каждой нити; локальные копии переменных инициализируются значениями этих переменных в нити-мастере;lastprivate(список) – переменным, перечисленным в списке, при-сваивается результат, полученный в последней секции;reduction(оператор:список) – задаёт оператор и список общих пе-ременных; для каждой переменной создаются локальные копии в каждой нити; локальные копии инициализируются соответственно типуоператора (для аддитивных операций – 0 или его аналоги, для мультипликативных операций – 1 или её аналоги); над локальными копиямипеременных после завершения всех секций выполняется заданный оператор; оператор это: для языка Си – +, *, -, &, |, ^, &&, ||, для языкаФортран – +, *, -, .and., .or., .eqv., .neqv., max, min, iand, ior,ieor; порядок выполнения операторов не определён, поэтому результат может отличаться от запуска к запуску;nowait – в конце блока секций происходит неявная барьерная синхро-низация параллельно работающих нитей: их дальнейшее выполнениепроисходит только тогда, когда все они достигнут данной точки; если вподобной задержке нет необходимости, опция nowait позволяет нитям,уже дошедшим до конца своих секций, продолжить выполнение безсинхронизации с остальными.Директива section задаёт участок кода внутри секции sections для выполнения одной нитью.Си:#pragma omp section48Фортран:!$omp sectionПеред первым участком кода в блоке sections директива section не обязательна.
Какие именно нити будут задействованы для выполнения какой секции, не специфицируется. Если количество нитей больше количества секций,то часть нитей для выполнения данного блока секций не будет задействована. Если количество нитей меньше количества секций, то некоторым (иливсем) нитям достанется более одной секции.Пример 21 иллюстрирует применение директивы sections. Cначала три нити, на которые распределились три секции section, выведут сообщение сосвоим номером, а потом все нити напечатают одинаковое сообщение со своим номером.#include <stdio.h>#include <omp.h>int main(int argc, char *argv[]){int n;#pragma omp parallel private(n){n=omp_get_thread_num();#pragma omp sections{#pragma omp section{printf("Первая секция, процесс %d\n", n);}#pragma omp section{printf("Вторая секция, процесс %d\n", n);}#pragma omp section{printf("Третья секция, процесс %d\n", n);}}printf("Параллельная область, процесс %d\n", n);}}Пример 21a.
Директива sections на языке Си.49!$omp!$omp!$omp!$omp!$omp!$omp!$ompprogram example21binclude "omp_lib.h"integer nparallel private(n)n=omp_get_thread_num()sectionssectionprint *, "Первая секция, процесс ", nsectionprint *, "Вторая секция, процесс ", nsectionprint *, "Третья секция, процесс ", nend sectionsprint *, "Параллельная область, процесс ", nend parallelendПример 21b. Директива sections на языке Фортран.Пример 22 демонстрирует использование опции lastprivate. В данномпримере опция lastprivate используется вместе с директивой sections.Переменная n объявлена как lastprivate переменная. Три нити, выполняющие секции section, присваивают своей локальной копии n разные значения. По выходе из области sections значение n из последней секции присваивается локальным копиям во всех нитях, поэтому все нити напечатаютчисло 3.
Это же значение сохранится для переменной n и в последовательнойобласти.50#include <stdio.h>#include <omp.h>int main(int argc, char *argv[]){int n=0;#pragma omp parallel{#pragma omp sections lastprivate(n){#pragma omp section{n=1;}#pragma omp section{n=2;}#pragma omp section{n=3;}}printf("Значение n на нити %d: %d\n",omp_get_thread_num(), n);}printf("Значение n в последовательной области: %d\n", n);}Пример 22a. Опция lastprivate на языке Си.program example22binclude "omp_lib.h"integer nn=0!$omp parallel!$omp sections lastprivate(n)!$omp sectionn=1;!$omp sectionn=2;!$omp sectionn=3;!$omp end sectionsprint *, "Значение n на нити ",&omp_get_thread_num(), ": ", n!$omp end parallelprint *, "Значение n в последовательной области: ", nendПример 22b.
Опция lastprivate на языке Фортран.51Директива workshareДиректива workshare ... end workshare используется для задания конечного (неитеративного) параллелизма программ, написанных на языке Фортран.!$omp workshare<блок операторов>!$omp end workshare [nowait]Блок между директивами определяет набор независимых операторов, каждыйиз которых выполняется своей нитью. В этот набор могут входить: присваивания массивов и скалярных переменных, операторы и конструкции FORALL,WHERE, директивы atomic, critical, parallel. При выполнении этого набора команд каждая такая операция выдаётся на исполнение отдельной нити(распределение операций по нитям зависит от реализации), при этом системаподдержки автоматически вставляет все необходимые по семантике синхронизации.
Например, система обеспечивает, чтобы операция не начиналась дотех пор, пока не будут полностью готовы все её аргументы. В конце конструкции предполагается неявная синхронизация работы нитей. Если в подобной синхронизации нет необходимости, то может быть использована опцияnowait.Пример 23 иллюстрирует применение директивы workshare. Сначала дваисходных массива инициализируются, затем в параллельной области задаётся область workshare, в которой производятся три массивные операции.Системой гарантируется, что третья операция не начнётся до того момента,пока не завершатся первые две.!$omp!$omp!$omp!$ompprogram example23real a(10), b(10), c(10), d(10), e(10)integer ido i=1, 10a(i) = ib(i) = 2*iend doparallel shared(a, b, c, d, e)worksharec=a+bd=b-ae=c+2*dend workshareend parallelprint *, "Результирующий массив: ", eendПример 23.
Директива workshare.52Задачи (tasks)Директива task (task ... end task) применяется для выделения отдельной независимой задачи.Си:#pragma omp task [опция [[,] опция]...]Фортран:!$omp task [опция [[,] опция]...]<код задачи>!$omp end taskТекущая нить выделяет в качестве задачи ассоциированный с директивойблок операторов. Задача может выполняться немедленно после создания илибыть отложенной на неопределённое время и выполняться по частям. Размертаких частей, а также порядок выполнения частей разных отложенных задачопределяется реализацией.Возможные опции:if(условие) — порождение новой задачи только при выполнении не-которого условия; если условие не выполняется, то задача будет выполнена текущей нитью и немедленно;untied — опция означает, что в случае откладывания задача можетбыть продолжена любой нитью из числа выполняющих данную параллельную область; если данная опция не указана, то задача может бытьпродолжена только породившей её нитью;default(private|firstprivate|shared|none) – всем переменным взадаче, которым явно не назначен класс, будет назначен класс private,firstprivate или shared соответственно; none означает, что всем пе-ременным в задаче класс должен быть назначен явно; в языке Си задаются только варианты shared или none;private(список) – задаёт список переменных, для которых порожда-ется локальная копия в каждой нити; начальное значение локальныхкопий переменных из списка не определено;firstprivate(список) – задаёт список переменных, для которых по-рождается локальная копия в каждой нити; локальные копии переменных инициализируются значениями этих переменных в нити-мастере;shared(список) – задаёт список переменных, общих для всех нитей.53Для гарантированного завершения в точке вызова всех запущенных задач используется директива taskwait.Си:#pragma omp taskwaitФортран:!$omp taskwaitНить, выполнившая данную директиву, приостанавливается до тех пор, покане будут завершены все ранее запущенные данной нитью независимые задачи.Задания• Могут ли функции omp_get_thread_num() и omp_get_num_threads()вернуть одинаковые значения на нескольких нитях одной параллельной области?• Можно ли распределить между нитями итерации цикла без использования директивы for (do ...
[end do])?• Можно ли одной директивой распределить между нитями итерациисразу нескольких циклов?• Возможно ли, что при статическом распределении итераций цикла нитям достанется разное количество итераций?• Могут ли при повторном запуске программы итерации распределяемого цикла достаться другим нитям? Если да, то при каких способах распределения итераций?• Для чего может быть полезно указывать параметр chunk при способераспределения итераций guided?• Можно ли реализовать параллельные секции без использования директив sections (sections ... end sections) и section?• Как при выходе из параллельных секций разослать значение некоторойлокальной переменной всем нитям, выполняющим данную параллельную область?• В каких случаях может пригодиться механизм задач?• Напишите параллельную программу, реализующую скалярное произведение двух векторов.• Напишите параллельную программу, реализующую поиск максимального значения вектора.54СинхронизацияЦелый набор директив в OpenMP предназначен для синхронизации работынитей.БарьерСамый распространенный способ синхронизации в OpenMP – барьер.
Оноформляется с помощью директивы barrier.Си:#pragma omp barrierФортран:!$omp barrierНити, выполняющие текущую параллельную область, дойдя до этой директивы, останавливаются и ждут, пока все нити не дойдут до этой точки программы, после чего разблокируются и продолжают работать дальше. Крометого, для разблокировки необходимо, чтобы все синхронизируемые нити завершили все порождённые ими задачи (task).Пример 24 демонстрирует применение директивы barrier.