Что такое findslide.org?

FindSlide.org - это сайт презентаций, докладов, шаблонов в формате PowerPoint.


Для правообладателей

Обратная связь

Email: Нажмите что бы посмотреть 

Яндекс.Метрика

Презентация на тему Лекция 2. Основные конструкции OpenMP

Содержание

Первый вопрос. Принципиальная схема программирования в OpenMP
ТЕОРИЯ РАЗРАБОТКИ КОРПОРАТИВНЫХ ИНФОРМАЦИОННЫХ СИСТЕМ.Лекция 2. Основные конструкции OpenMP. Первый вопрос.        Принципиальная схема программирования в OpenMP Любая программа, последовательная или параллельная, состоит из набора областей двух типов: последовательных Принципиальная схема параллельной программы При выполнении параллельной программы работа начинается с инициализации Выполнение параллельных потоков в параллельной области программы начинается с их инициализации. Она Второй вопрос.        Синтаксис директив в OpenMP Основные конструкции OpenMP - это директивы компилятора или прагмы (директивы препроцессора) языка Общий вид основных директив OpenMP на языке C/C++.# pragma omp parallel Особенности реализации директив OpenMP	Количество потоков в параллельной программе определяется либо значением переменной Определить номер текущего потока можно с помощью функции omp_get_thread_num().Каждый поток выполняет В OpenMP существуют различные режимы выполнения (Execution Mode) параллельных структурных блоков. Возможны Статический режим (Static Mode). Этот режим определяется заданием переменной окружения OMP_STATIC в Директивы OpenMPДирективы shared, private и defaultЭти директивы (предложения OpenMP) используются для описания В качестве иллюстрации использования директив OpenMP shared и private рассмотрим фрагмент программы. Директивы firstprivate и lastprivateДирективы (предложения) OpenMP firstprivate и lastprivate используются для описания Предложение OpenMPlastprivate( var1, var2, ..., varN ) определяет переменные var1, var2, ..., Директива if	Директива (предложение) OpenMP if используется для организации условного выполнения потоков в Директива reduction	Директива OpenMP reduction позволяет собрать вместе в главном потоке результаты вычислений В языке Fortran в качестве параметров operator и intrinsic в предложениях reduction Директива copyin	Директива OpenMP copyin используется для передачи данных из главного потока в В качестве иллюстрации миграции данных рассмотрим фрагмент Fortran-программы.  В этом примере Директива for	Директива OpenMP for используется для организации параллельного выполнения петель циклов в
Слайды презентации

Слайд 2 Первый вопрос.

Первый вопрос.    Принципиальная схема программирования в OpenMP


Принципиальная схема программирования в OpenMP


Слайд 3 Любая программа, последовательная или параллельная, состоит из набора

Любая программа, последовательная или параллельная, состоит из набора областей двух типов:

областей двух типов: последовательных областей и областей распараллеливания. При

выполнении последовательных областей порождается только один главный поток (процесс). В этом же потоке инициируется выполнение программы, а также происходит ее завершение. В последовательной программе в областях распараллеливания порождается также только один, главный поток, и этот поток является единственным на протяжении выполнения всей программы. В параллельной программе в областях распараллеливания порождается целый ряд параллельных потоков. Порожденные параллельные потоки могут выполняться как на разных процессорах, так и на одном процессоре вычислительной системы. В последнем случае параллельные процессы (потоки) конкурируют между собой за доступ к процессору. Управление конкуренцией осуществляется планировщиком операционной системы с помощью специальных алгоритмов. В операционной системе Linux планировщик задач осуществляет обработку процессов с помощью стандартного карусельного ( round-robin ) алгоритма. При этом только администраторы системы имеют возможность изменить или заменить этот алгоритм системными средствами. Таким образом, в параллельных программах в областях распараллеливания выполняется ряд параллельных потоков.

Слайд 4
Принципиальная схема параллельной программы
При выполнении параллельной программы

Принципиальная схема параллельной программы При выполнении параллельной программы работа начинается с

работа начинается с инициализации и выполнения главного потока (процесса),

который по мере необходимости создает и выполняет параллельные потоки, передавая им необходимые данные. Параллельные потоки из одной параллельной области программы могут выполняться как независимо друг от друга, так и с пересылкой и получением сообщений от других параллельных потоков. Последнее обстоятельство усложняет разработку программы, поскольку в этом случае программисту приходится заниматься планированием, организацией и синхронизацией посылки сообщений между параллельными потоками. Таким образом, при разработке параллельной программы желательно выделять такие области распараллеливания, в которых можно организовать выполнение независимых параллельных потоков. Для обмена данными между параллельными процессами (потоками) в OpenMP используются общие переменные. При обращении к общим переменным в различных параллельных потоках возможно возникновение конфликтных ситуаций при доступе к данным. Для предотвращения конфликтов можно воспользоваться процедурой синхронизации ( synchronization ). При этом надо иметь в виду, что процедура синхронизации - очень дорогая операция по временным затратам и желательно по возможности избегать ее или применять как можно реже. Для этого необходимо очень тщательно продумывать структуру данных программы.

Слайд 5

Выполнение параллельных потоков в параллельной области программы начинается

Выполнение параллельных потоков в параллельной области программы начинается с их инициализации.

с их инициализации. Она заключается в создании дескрипторов порождаемых

потоков и копировании всех данных из области данных главного потока в области данных создаваемых параллельных потоков. Эта операция чрезвычайно трудоемка - она эквивалентна примерно трудоемкости 1000 операций.

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

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

Вывод: при выделении параллельных областей программы и разработке параллельных процессов необходимо, чтобы трудоемкость параллельных процессов была не менее 2000 операций деления. В противном случае параллельный вариант программы будет проигрывать в быстродействии последовательной программе. Для эффективной работающей параллельной программы этот предел должен быть существенно превышен.

Слайд 6 Второй вопрос.

Второй вопрос.    Синтаксис директив в OpenMP


Синтаксис директив в OpenMP


Слайд 7 Основные конструкции OpenMP - это директивы компилятора или

Основные конструкции OpenMP - это директивы компилятора или прагмы (директивы препроцессора)

прагмы (директивы препроцессора) языка C/C++.
Общий вид директивы OpenMP


#pragma omp конструкция [предложение [предложение] … ]
Большинство директив OpenMP применяется к структурным блокам. Структурные блоки - это последовательности операторов с одной точкой входа в начале блока и одной точкой выхода в конце блока.

Пример 2.1. Пример структурного блока в программе на языке Fortran
c$omp parallel
10 wrk (id) = junk (id)
res (id) = wrk (id)**2
if (conv (res)) goto 10
c$omp end parallel
print *, id

Пример 2.2. Пример неструктурного блока в программе на языке Fortran

c$omp parallel
10 wrk (id) = junk (id)
30 res (id) = wrk (id)**2
if (conv (res)) goto 20
goto 10c$omp end parallel
if (not_done) goto 30 20 print *, id

Слайд 8
Общий вид основных директив OpenMP на языке C/C++.
#

Общий вид основных директив OpenMP на языке C/C++.# pragma omp parallel

pragma omp parallel \

private (var1, var2, …) \
shared (var1, var2, …) \
firstprivate (var1, var2, …) \
lastprivate (var1, var2, …) \
copyin (var1, var2, …) \
reduction (operator: var1, var 2, …) \
if (expression) \
default (shared | none) \
{ [ Структурный блок программы]}

Предложение OpenMP shared используется для описания общих переменных. Предложение private используется для описания внутренних (локальных) переменных для каждого параллельного процесса. Предложение firstprivate применяется для описания внутренних переменных параллельных процессов, однако данные в эти переменные импортируются из главного потока. Предложение reduction позволяет собрать вместе в главном потоке результаты вычислений частичных сумм, разностей и т. п. из параллельных потоков. Предложение if является условным оператором в параллельном блоке. Предложение default определяет по умолчанию тип всех переменных в последующем параллельном структурном блоке программы.
Предложение copyin позволяет легко и просто передавать данные из главного потока в параллельные.
Для продолжения длинных директив на следующих строках в программах на C/C++ применяется символ "обратный слэш" в конце строки.

Слайд 9
Особенности реализации директив OpenMP

Количество потоков в параллельной программе

Особенности реализации директив OpenMP	Количество потоков в параллельной программе определяется либо значением

определяется либо значением переменной окружения OMP_NUM_THREADS, либо специальными функциями,

вызываемыми внутри самой программы.
Задание переменной окружения OMP_NUM_THREADS в операционной системе Linux осуществляется следующим образом с помощью команды

export OMP_NUM_THREADS=256
Здесь было задано 256 параллельных потоков.
Просмотреть состояние переменной окружения OMP_NUM_THREADS можно, например, с помощью следующей команды:

export | grep OMP_NUM_THREADS

Каждый поток имеет свой номер thread_number, начинающийся от нуля (для главного потока) и заканчивающийся OMP_NUM_THREADS-1.


Слайд 10 Определить номер текущего потока можно с помощью

Определить номер текущего потока можно с помощью функции omp_get_thread_num().Каждый поток

функции omp_get_thread_num().
Каждый поток выполняет структурный блок программы, включенный в

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

Пример ветвления во фрагменте программы в зависимости от номера параллельного потока
#pragma omp parallel
{
myid = omp_get_thread_num ( ) ;
if (myid == 0) do_something ( ) ;
else do_something_else (myid) ;}
В этом примере в первой строке параллельного блока вызывается функция omp_get_thread_num, возвращающая номер параллельного потока. Этот номер сохраняется в локальной переменной myid. Далее в зависимости от значения переменной myid вызывается либо функция do_something() в первом параллельном потоке с номером 0, либо функция do_something_else(myid) во всех остальных параллельных потоках.

Слайд 11 В OpenMP существуют различные режимы выполнения (Execution Mode)

В OpenMP существуют различные режимы выполнения (Execution Mode) параллельных структурных блоков.

параллельных структурных блоков.

Возможны следующие режимы:
Динамический режим (Dynamic Mode).

Этот режим установлен по умолчанию и определяется заданием переменной окружения OMP_DYNAMIC в операционной системе Linux.
Задать эту переменную можно, например, с помощью следующей команды операционной системы Linux:
export OMP_DYNAMIC
Кроме того, существует возможность задать этот режим и саму переменную внутри программы, вызвав функцию
omp_set_dynamic()

Отметим, что на компьютерах Silicon Graphics S350 и Kraftway G-Scale S350 вторая возможность отсутствует.
В динамическом режиме количество потоков определяется самой операционной системой в соответствии со значением переменной окружения OMP_NUM_THREADS.
В процессе выполнения параллельной программы при переходе от одной области распараллеливания к другой эта переменная может изменять свое значение;


Слайд 12 Статический режим (Static Mode). Этот режим определяется заданием

Статический режим (Static Mode). Этот режим определяется заданием переменной окружения OMP_STATIC

переменной окружения OMP_STATIC в операционной системе Linux. В этом

случае количество потоков определяется программистом.
Задать переменную окружения OMP_STATIC можно, например, с помощью следующей команды операционной системы Linux:
export OMP_STATIC
Кроме того, существует возможность задать этот режим и саму переменную внутри программы, вызвав функцию
omp_set_static()
Однако на компьютерах Silicon Graphics S350 и Kraftway G-Scale S350 вторая возможность отсутствует;

Параллельные структурные блоки могут быть вложенными, но компилятор иногда по ряду причин может выполнять их и последовательно в рамках одного потока. Вложенный режим выполнения параллельных структурных блоков определяется заданием переменной окружения OMP_NESTED=[FALSE|TRUE] (по умолчанию задается FALSE ) в операционной системе Linux.
Задать эту переменную можно, например, с помощью следующей команды операционной системы Linux:
setenv OMP_NESTED TRUE
Кроме того, существует возможность задать этот режим и саму переменную внутри программы, вызвав функцию
omp_set_nested( TRUE | FALSE )

Слайд 13
Директивы OpenMP

Директивы shared, private и default
Эти директивы (предложения

Директивы OpenMPДирективы shared, private и defaultЭти директивы (предложения OpenMP) используются для

OpenMP) используются для описания типов переменных внутри параллельных потоков.

Предложение

OpenMP shared( var1, var2, …, varN )
определяет переменные var1, var2, …, varN как общие переменные для всех потоков.
Они размещаются в одной и той же области памяти для всех потоков.

Предложение OpenMP private( var1, var2, …, varN )
определяет переменные var1, var2, …, varN как локальные переменные для каждого из параллельных потоков.

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


Слайд 14 В качестве иллюстрации использования директив OpenMP shared и

В качестве иллюстрации использования директив OpenMP shared и private рассмотрим фрагмент

private рассмотрим фрагмент программы.
В этом примере переменная a

определена как общая и является идентификатором одномерного массива.
Переменные myid и x определены как локальные переменные для каждого из параллельных потоков.
В каждом из параллельных потоков локальные переменные получают собственные значения. После чего при выполнении условия x<1.0 значение локальной переменной x присваивается myid -й компоненте общего для всех потоков массива a. Значение x будет неопределенным, если не определить x как переменную типа private.
Отметим, что значения private -переменных не определены до и после блока параллельных вычислений.

Пример использования директив OpenMP shared и private в параллельной области программы
c$omp parallel shared (a)
c$omp& private (myid, x)
myid = omp_get_thread_num ( )
x = work (myid)
if (x < 1.0) then
a (myid) = x
endif
Предложение OpenMP default ( shared | private | none )
задает тип всех переменных, определяемых по умолчанию в последующем параллельном структурном блоке как shared, private или none.
Например, если во фрагменте программы вместо private( myid, x ) написать
default( private ) то определяемые далее по умолчанию переменные myid и x будут автоматически определены как private.


Слайд 15 Директивы firstprivate и lastprivate
Директивы (предложения) OpenMP firstprivate и

Директивы firstprivate и lastprivateДирективы (предложения) OpenMP firstprivate и lastprivate используются для

lastprivate используются для описания локальных переменных, инициализируемых внутри параллельных

потоков.
Переменные, описанные как firstprivate, получают свои значения из последовательной части программы.
Переменные, описанные как lastprivate, сохраняют свои значения при выходе из параллельных потоков при условии их последовательного выполнения.
Предложение OpenMP
firstprivate( var1, var2, ..., varN )
определяет переменные var1, var2, ..., varN как локальные переменные для каждого из параллельных потоков, причем инициализация значений этих переменных происходит в самом начале параллельного структурного блока по значениям из предшествующего последовательного структурного блока программы.
В качестве иллюстрации рассмотрим фрагмент программы.
program first
integer :: myid, c
integer, external :: omp_get_thread_num
c=98
!$omp parallel private (myid)
!$omp& firstprivate (c)
myid = omp_get_thread_num ( )
write (6, *) 'T: ', myid, 'c=', c
!$omp end parallel
end program first
T:1 с=98 T:3 с=98 T:2 с=98 T:0 с=98
В этом примере в каждом параллельном потоке используется своя переменная c, но значение этой переменной перед входом в параллельный блок программы берется из предшествующего последовательного блока.


Слайд 16 Предложение OpenMP

lastprivate( var1, var2, ..., varN )

определяет

Предложение OpenMPlastprivate( var1, var2, ..., varN ) определяет переменные var1, var2,

переменные var1, var2, ..., varN как локальные переменные для

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

В качестве иллюстрации рассмотрим фрагмент программы.
В этом примере локальная переменная i принимает различные значения в каждом потоке параллельного структурного блока. После завершения параллельного структурного блока переменная i сохраняет свое последнее значение, полученное в последнем параллельном потоке, при условии последовательного выполнения всех параллельных потоков, т. е. n=N+1.

c$omp do shared ( x )
c$omp& lastprivate ( i)
do i = 1, N
x (i) = a
enddo
n = i

Слайд 17

Директива if

Директива (предложение) OpenMP if используется для организации

Директива if	Директива (предложение) OpenMP if используется для организации условного выполнения потоков

условного выполнения потоков в параллельном структурном блоке.
Предложение OpenMP
if( expression

)
определяет условие выполнения параллельных потоков в последующем параллельном структурном блоке.
Если выражение expression принимает значение TRUE (Истина), то потоки в последующем параллельном структурном блоке выполняются. В противном случае, когда выражение expression принимает значение FALSE (Ложь), потоки в последующем параллельном структурном блоке не выполняются.
В качестве иллюстрации рассмотрим фрагмент программы.
c$omp parallel do if (n .ge. 2000)
do i = 1, n
a (i) = b (i)*c + d (i)
enddo

В этом примере цикл распараллеливается только в том случае
(n>2000), когда параллельная версия будет заведомо быстрее последовательной.
Напомним, что трудоемкость образования параллельных потоков эквивалентна примерно трудоемкости 1000 операций.

Слайд 18 Директива reduction
Директива OpenMP reduction позволяет собрать вместе в

Директива reduction	Директива OpenMP reduction позволяет собрать вместе в главном потоке результаты

главном потоке результаты вычислений частичных сумм, разностей и т.

п. из параллельных потоков последующего параллельного структурного блока.
В предложении OpenMP
reduction( operator | intrinsic: var1 [, var2,..., varN]) определяется operator - операции ( +, -, *, / и т. п.) или функции, для которых будут вычисляться соответствующие частичные значения в параллельных потоках последующего параллельного структурного блока.
Кроме того, определяется список локальных переменных var1, var2, ..., varN, в котором будут сохраняться соответствующие частичные значения. После завершения всех параллельных процессов частичные значения складываются (вычитаются, перемножаются и т. п.), и результат сохраняется в одноименной общей переменной.
В качестве иллюстрации рассмотрим фрагмент программы.
c$omp do shared (x) private (i)
c$omp& reduction (+ : sum)
do i = 1, N
sum = sum + x (I)
enddo
В этом примере в каждом параллельном потоке определена локальная переменная sum для вычисления частичных сумм. После завершения параллельных потоков все локальные переменные sum суммируются, а результат сохраняется в одноименной общей (глобальной) переменной sum.

Слайд 19
В языке Fortran в качестве параметров operator и

В языке Fortran в качестве параметров operator и intrinsic в предложениях

intrinsic в предложениях reduction допускаются следующие операции и функции:
параметр

operator может быть одной из следующих арифметических или логических операций: +, -, *, .and. , .or. , .eqv. , .neqv.;
параметр intrinsic может быть одной из следующих функций: max, min, iand, ior, ieor.

В языке C/C++ в качестве параметров operator и intrinsic в предложениях reduction допускаются следующие операции и функции:
параметр operator может быть одной из следующих арифметических или логических операций: +, -, *, &, ^, &&, || ;
параметр intrinsic может быть одной из следующих функций: max, min ;
указатели и ссылки в предложениях reduction использовать строго запрещено!


Слайд 20 Директива copyin
Директива OpenMP copyin используется для передачи данных

Директива copyin	Директива OpenMP copyin используется для передачи данных из главного потока

из главного потока в параллельные потоки, называемой миграцией данных.

Механизмы реализации этой директивы в языках C/C++ и Fortran различны. Рассмотрим далее реализации этой директивы поочередно в C/C++ и Fortran.

Предложение OpenMP в языке C/C++

copyin( var1 [, var2[, ...[, varN]]] )

определяет список локальных переменных var1, var2, ..., varN, которым присваиваются значения из одноименных общих переменных, заданных в глобальном потоке.

В Fortran в качестве параметров директивы OpenMP copyin задаются имена common -блоков ( cb1, cb2, ..., cbN ), в которых описаны мигрирующие переменные
copyin( /cb1/ [, /cb2/ [, ...[, /cbN/ ]]] )

т.е. такие переменные из глобального потока, которые передают свои значения своим копиям, определенным в параллельных потоках в качестве локальных переменных.

Слайд 21 В качестве иллюстрации миграции данных рассмотрим фрагмент Fortran-программы.

В качестве иллюстрации миграции данных рассмотрим фрагмент Fortran-программы. В этом примере

В этом примере мигрирующая целочисленная переменная x хранится в

common -блоке mine. Значение этой общей переменной задается в главном потоке. В каждом параллельном потоке используется своя локальная переменная х, которой присваивается значение общей переменной x. integer : : x, tid integer, external :: omp_get_thread_num ( ) common/mine/ x ! $omp threadprivate (/mine/) x=33 call omp_set_num_threads (4) ! $omp parallel private (tid) copyin (/mine/) tid=omp_get_thread_num ( ) print *, 'T: ',tid, ' x = ', x ! $omp end parallel Результаты работы программы: T: 1 x = 33 T: 2 x = 33 T: 0 x = 33 T: 3 x = 33

  • Имя файла: lektsiya-2-osnovnye-konstruktsii-openmp.pptx
  • Количество просмотров: 130
  • Количество скачиваний: 0