Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекция по ПП 3.pdf
Скачиваний:
13
Добавлен:
02.06.2015
Размер:
4.72 Mб
Скачать

Пример

Задача: Распараллелить следующий цикл for (i=0; i < NumElements; i++)

{

array[i] = StartVal;

StartVal++;

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

Примеры

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

#pragma omp parallel for

for (i=0; i < NumElements; i++)

{

array[i] = StartVal + i;

}

ОбратитеПримерывнимание, что данный код не на 100% совпадает с первоначальным, поскольку отсутствуетприращение переменной StartVal.

В результате после завершения параллельного цикла эта переменная будет иметь значение, отличное от того, которое получается в последовательной версии. Если значение StartVal используется после цикла, требуется дополнительный оператор,

Примеры

//Thisworksandisidenticaltotheserial version.

#pragmaompparallelfor for(i=0;i<NumElements;i++)

{

array[i]=StartVal+i;

}

StartVal+=NumElements;

Базовыеконструкции

Директиваparallel

Чтобыпродемонстрироватьзапуск несколькихпотоковраспараллелим следующий блоктекста:

#pragma omp parallel

 

for(d1 = 0; d1 <= 9; d1++)

 

for(d2 = 0; d2 <= 9; d2++)

 

for(d3 = 0; d3 <= 9; d3++)

 

for(d4 = 0; d4 <= 9; d4++)

 

for(d5 = 0; d5 <= 9; d5++)

 

for(d6 = 0; d6 <= 9; d6++)

 

if(d1 + d2 + d3 == d4 + d5 + d6)

 

iResult++;

62

Базовыеконструкции

Директиваparallel

Привыполнениипрограммыполучен неверныйрезультат:

Приверномвыполнениипрограммы количество«счастливыхбилетиков» должно быть55252шт.:

63

Базовыеконструкции

Директиваfor Директива

#pragma omp for

сообщает, чтопривыполнении циклаfor впараллельномрегионе итерациицикладолжныбыть распределенымеждупотоками группы

64

Базовыеконструкции

Директиваfor

Сдобавлениемдирективыfor получим:

#pragma omp parallel for

 

for(d1 = 0; d1 <= 9; d1++)

 

for(d2 = 0; d2 <= 9; d2++)

 

for(d3 = 0; d3 <= 9; d3++)

 

for(d4 = 0; d4 <= 9; d4++)

 

for(d5 = 0; d5 <= 9; d5++)

 

for(d6 = 0; d6 <= 9; d6++)

 

if(d1 + d2 + d3 == d4 + d5 + d6)

 

iResult++;

65

Базовыеконструкции

Директивыprivate иshared

Относительнопараллельных регионовданныемогут быть общими

(shared)иличастными(private)

Частныеданныепринадлежатпотоку имогут бытьмодифицированытолько им

Общиеданныедоступнывсем потокам

66

Базовыеконструкции

Директивыprivate иshared

Врассматриваемомранеепримере переменныеd1-d6былиобщими

if(d1 + d2 + d3 == d4 + d5 + d6)

Врезультатепеременныеначнут использоватьсявсемипотоками одновременно,чтоприведеткгонкам

67

Базовыеконструкции

Директивыprivate иshared

Чтобысделатьпеременнуюдлякаждого потокачастной(private)можно воспользоватьсядирективойprivate:

68

Базовыеконструкции

Директивыprivate иshared

#pragma omp parallel for private(d1,d2,d3,d4,d5,d6)

for(d1 = 0; d1 <= 9; d1++) for(d2 = 0; d2 <= 9; d2++) for(d3 = 0; d3 <= 9; d3++) for(d4 = 0; d4 <= 9; d4++) for(d5 = 0; d5 <= 9; d5++) for(d6 = 0; d6 <= 9; d6++)

if(d1 + d2 + d3 == d4 + d5 + d6) iResult++;

69

Базовыеконструкции

Директиваatomic

Данноераспараллеливаниенекорректно,таккак впроцессеработынесколькопотоковпытаются

одновременнообращатьсякпеременнойiResult длячтенияизаписи:

#pragma omp parallel for

 

private(d1,d2,d3,d4,d5,d6)

 

for(d1 = 0; d1 <= 9; d1++)

 

for(d2 = 0; d2 <= 9; d2++)

 

for(d3 = 0; d3 <= 9; d3++)

 

for(d4 = 0; d4 <= 9; d4++)

 

for(d5 = 0; d5 <= 9; d5++)

 

for(d6 = 0; d6 <= 9; d6++)

 

if(d1 + d2 + d3 == d4 + d5 + d6)

70

Базовыеконструкции

Директиваatomic

Внекорректностираспараллеливания такжеможноубедитьсянапрактике, запустивдемонстрационныйкод:

71

Базовыеконструкции

Директиваatomic

Сприменениемдирективыatomic код будетвыглядетьтак:

#pragma omp parallel for

 

private(d1,d2,d3,d4,d5,d6)

 

for(d1 = 0; d1 <= 9; d1++)

 

for(d2 = 0; d2 <= 9; d2++)

 

for(d3 = 0; d3 <= 9; d3++)

 

for(d4 = 0; d4 <= 9; d4++)

 

for(d5 = 0; d5 <= 9; d5++)

 

for(d6 = 0; d6 <= 9; d6++)

 

if(d1 + d2 + d3 == d4 + d5 + d6)

 

#pragma omp atomic

72

Базовыеконструкции

Директиваatomic

Данноерешениедаеткорректный результат:

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

73

Базовыеконструкции

Директиваreduction Форматдирективы:

reduction(оператор:список)

Возможные

 

 

Список—

 

операторы:

 

 

перечисляет

o "+","*","-","&"

 

 

именаобщих

 

 

переменных(тип

o "|","^"

 

 

 

 

float, intилиlong)

o "&&","||"

 

 

 

 

 

74

Базовыеконструкции

Директиваreduction

Принципработы:

1.Длякаждойпеременнойсоздаются локальныекопии вкаждомпотоке

2.Локальныекопии инициализируются соответственнотипуоператора

3.Надлокальнымикопиями переменных послевыполнениявсех операторов параллельнойобластивыполняется заданныйоператор

75

Базовыеконструкции

Директиваreduction

Теперьсиспользованием«reduction», эффективноработающийкод приметвид:

#pragma omp parallel for private(d1,d2,d3,d4,d5,d6) reduction(+:iResult)

for(d1 = 0; d1 <= 9; d1++) for(d2 = 0; d2 <= 9; d2++) for(d3 = 0; d3 <= 9; d3++) for(d4 = 0; d4 <= 9; d4++) for(d5 = 0; d5 <= 9; d5++) for(d6 = 0; d6 <= 9; d6++)

if(d1 + d2 + d3 == d4 + d5 + d6) iResult++;

76

КострукцииOpenMP

конструкции длясозданияпотоков

(директиваparallel),

конструкции распределенияработы междупотоками(директивыDO/forи section),

конструкции дляуправленияработой с данными(выраженияsharedиprivateдля определенияклассапамятипеременных),

77

КострукцииOpenMP

конструкции длясинхронизациипотоков

(директивыcritical,atomicиbarrier),

процедурыбиблиотекиподдержки временивыполнения(например, omp_get_thread_num),

переменныеокружения(например, OMP_NUM_THREADS).

78

Конструкциидлясозданияпотоков:

директиваparallel

#pragma omp parallel опция[[[,] опция]...]

структурированный блок

Возможныеопции:

if(условие)– выполнениепараллельной области поусловию.Вхождениев параллельнуюобласть осуществляется только привыполнениинекоторого условия.Еслиусловиеневыполнено,то директиванесрабатываетипродолжается обработка программывпрежнемрежиме;

79

Конструкциидлясозданияпотоков: директиваparallel

Выполнениепараллельнойобласти по условию.

#pragma omp parallel if (x)

80

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

num_threads(целочисленноевыражение)– явноезаданиеколичестванитей,которые будутвыполнять параллельнуюобласть;

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

OMP_NUM_THREADS;

81

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

default(shared|none)– всемпеременнымв параллельной области,которым явноне назначенкласс,будетназначенкласс shared;none означает,чтовсем переменнымвпараллельнойобласти класс долженбытьназначенявно;

82

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

private(список) – задаётсписок переменных,для которых порождается локальная копия вкаждой нити;начальное значениелокальныхкопийпеременныхиз списканеопределено;

83

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

firstprivate(список)– задаётсписок переменных,для которых порождается локальная копия вкаждой нити;локальные копиипеременныхинициализируются значениямиэтихпеременныхвнитимастере;

84

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

shared(список)– задаётсписок переменных,общихдлявсехнитей;

85

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

copyin(список)– задаётсписок переменных,объявленныхкак threadprivate,которые привходев параллельнуюобласть инициализируются значениямисоответствующихпеременных внити-мастере;

86

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

reduction(оператор:список) – задаёт оператор исписокобщихпеременных;

длякаждой переменнойсоздаются локальные копиивкаждой нити;

87

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

reduction(оператор:список)

локальныекопииинициализируются соответственно типуоператора(для аддитивныхопераций– 0илиего аналоги,длямультипликативных операций– 1илиеёаналоги);

88

Конструкциидлясозданияпотоков: директиваparallel

Возможныеопции:

reduction(оператор:список)

надлокальными копиямипеременных послевыполнениявсехоператоров параллельной областивыполняется заданныйоператор;

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

89

Конструкциидлясозданияпотоков: директиваparallel

Привходевпараллельнуюобласть порождаются новые

OMP_NUM_THREADS-1 нитей,каждая нитьполучаетсвойуникальныйномер, причёмпорождающая нитьполучает номер0истановитсяосновной нитью группы(“мастером”).

90

Конструкциидлясозданияпотоков: директиваparallel

Остальныенитиполучаютвкачестве номерацелыечислас1до

OMP_NUM_THREADS-1. Количество нитей,выполняющихданную параллельнуюобласть, остаётся неизменнымдомоментавыходаиз области.

91

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

private(список)– задаётсписок переменных,для которых порождается локальная копия вкаждой нити; начальноезначениелокальных копий переменныхизсписканеопределено;

103

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

firstprivate(список)– задаётсписок переменных,для которых порождается локальная копия вкаждой нити; локальные копиипеременных инициализируютсязначениямиэтих переменныхвнити-мастере;

104

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

lastprivate(список)– переменным, перечисленнымвсписке,присваивается результатспоследнеговиткацикла;

105

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

reduction(оператор:список) – задаёт оператор исписокобщихпеременных; длякаждой переменнойсоздаются локальные копиивкаждой нити; локальныекопииинициализируются соответственно типуоператора;

106

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

schedule(type[,chunk]) – опциязадаёт,

какимобразом итерациицикла распределяютсямеждунитями;

107

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

collapse(n)– опцияуказывает,чтоn последовательныхтесновложенных цикловассоциируетсясданной директивой;

108

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

collapse(n)–

еслиопцияcollapseнезадана,то директиваотносится только кодному непосредственноследующемузаней циклу;

109

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

ordered– опция,говорящая отом, чтов циклемогутвстречатьсядирективы ordered;вэтомслучаеопределяетсяблок внутрителацикла,который должен выполнятьсявтом порядке,вкотором итерацииидутвпоследовательномцикле;

110

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

nowait– вконцепараллельного цикла происходитнеявнаябарьерная синхронизацияпараллельноработающих нитей:ихдальнейшеевыполнение происходиттолько тогда, когдавсеони достигнутданнойточки;

111

Опциидирективыfor

#pragmaompforопция[[[,] опция]... ]

циклfor Возможныеопции:

nowait–

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

112

Конструкциираспределенияработы междупотоками:директиваsingle

Есливпараллельнойобласти какой-либо участоккодадолженбытьвыполненлишь одинраз,тоегонужновыделить директивойsingle.

#pragmaompsingleопция[[[,]опция]...]

структурированный блок

113

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

private(список) – задаётсписок переменных,для которых порождается локальная копия в каждой нити;начальноезначение локальных копийпеременныхиз списканеопределено;

114

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

firstprivate(список)– задаётсписок переменных,для которых порождается локальная копия в каждой нити;локальные копии переменныхинициализируются значениямиэтихпеременныхвнитимастере;

115

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

copyprivate(список)– послевыполнения нити,содержащейконструкциюsingle, новыезначенияпеременныхсписка будутдоступнывсемодноименным частнымпеременным(privateи firstprivate),описаннымвначале параллельнойобластиииспользуемым всемиеёнитями;.

116

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

copyprivate(список)–

опциянеможетиспользоваться совместносопциейnowait;

переменныесписканедолжныбыть перечисленывопцияхprivateи firstprivateданнойдирективыsingle;

117

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

nowait– послевыполнениявыделенного участкапроисходитнеявнаябарьерная синхронизацияпараллельно работающихнитей:ихдальнейшее выполнениепроисходиттолько тогда, когда всеонидостигнутданнойточки;

118

Конструкциираспределенияработы междупотоками:директиваsingle

Возможныеопции:

nowait–

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

.

119

Конструкциираспределенияработы междупотоками:директиваsingle

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

120

Конструкциираспределенияработы междупотоками:директиваsingle

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

121

Конструкциираспределенияработы междупотоками:директиваsingle

Какаяименнонитьбудетвыполнять выделенныйучастокпрограммы,не специфицируется.Однанитьбудет выполнять данныйфрагмент,авсе остальные нитибудутожидать завершения еёработы,еслитолько неуказанаопция nowait.

.

122

Конструкциираспределенияработы междупотоками:директиваsingle

Следующийпримериллюстрирует применениеопцииcopyprivate.

Вданномпримерепеременнаяn объявленавпараллельной областикак локальная.

Каждаянитьприсвоитпеременнойn значение,равноесвоемупорядковому номеру,инапечатаетданноезначение.

123

Конструкциираспределенияработы междупотоками:директиваsingle

Вобластиsingleоднаизнитейприсвоит переменнойnзначение100,инавыходеиз области этозначениебудетприсвоено переменнойnнавсехнитях.

Вконцепараллельной областизначениеn печатаетсяещёразинавсехнитяхоно равно100.

124

Конструкциираспределенияработы междупотоками:директиваsingle

#include <stdio.h> #include <omp.h>

intmain(int argc,char*argv[])

{

intn;

#pragmaompparallelprivate(n)

{

n=omp_get_thread_num(); printf("Значениеnначало():%d\n",n);

125

Конструкциираспределенияработы междупотоками:директиваsingle

#pragmaompsinglecopyprivate(n)

{

n=100;

}

printf("Значениеnконец():%d\n",n);

}

}

126

Конструкциираспределенияработы междупотоками:директиваsingle

Ограничениядлядирективыsingle следующие:

опцияcopyprivateнедолжна использоватьсявместесопциейnowait;

только однаопцияnowaitможетбыть использованавдирективеsingle;

исключениевобласти single должно быть обработанно врамкаходной области single,однойитойженитью.

127

Конструкциираспределенияработы

междупотоками:директиваsections

Директиваsections используетсядля заданияконечного (неитеративного) параллелизма.

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

Каждыйструктурированный блок исполняетсяодинразоднимизпотоков в группе.

128

Конструкциираспределенияработы

междупотоками:директиваsections

#pragmaompsectionsопция[[[,] опция]...]

{

#pragmaompsection

структурированный блок

#pragmaompsection

структурированный блок

...

}

129

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

private(список) – задаётсписок переменных,для которых порождается локальная копия вкаждой нити; начальноезначениелокальных копий переменныхизсписканеопределено;

130

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

firstprivate(список)– задаётсписок переменных,для которых порождается локальная копия вкаждой нити; локальные копиипеременных инициализируютсязначениямиэтих переменныхвнити-мастере;

131

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

lastprivate(список)– переменным, перечисленнымвсписке,присваивается результат,полученныйвпоследней секции;

132

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

reduction(оператор:список) – задаёт оператор исписокобщихпеременных; длякаждой переменнойсоздаются локальные копиивкаждой нити;

133

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

nowait– вконцеблокасекций происходитнеявнаябарьерная синхронизацияпараллельно работающихнитей:ихдальнейшее выполнениепроисходиттолько тогда, когда всеонидостигнутданнойточки;

134

Конструкциираспределенияработы

междупотоками:директиваsections

Возможныеопции:

nowait–

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

135

Конструкциираспределенияработы

междупотоками:директиваsections

Директиваsectionзадаётучастоккода внутрисекцииsections длявыполнения одной нитью.

#pragmaompsection

136

Конструкциираспределенияработы

междупотоками:директиваsections

Передпервымучасткомкодавблоке sections директиваsectionнеобязательна. Какиеименнонитибудутзадействованы длявыполнениякакой секции,не специфицируется.

137

Конструкциираспределенияработы

междупотоками:директиваsections

Есликоличествонитейбольшеколичества секций,точастьнитейдлявыполнения данногоблокасекцийнебудет задействована.Есликоличествонитей меньшеколичествасекций,тонекоторым (иливсем)нитям достанетсяболееодной секции.

138

Конструкциираспределенияработы

междупотоками:директиваsections

Следующийпримердемонстрирует использованиеопцииlastprivate.

Вданномпримереопцияlastprivate используетсявместесдирективой sections.

139

Конструкциираспределенияработы

междупотоками:директиваsections

Переменнаяnобъявленакакlastprivate переменная.

Тринити,выполняющиесекцииsection, присваиваютсвоейлокальной копии n разныезначения.

140

Конструкциираспределенияработы

междупотоками:директиваsections

Повыходеизобластиsections значениеn изпоследнейсекцииприсваивается локальным копиям вовсехнитях, поэтому всенитинапечатаютчисло3.

Это жезначениесохранится для переменнойn ивпоследовательной области.

141

Конструкциираспределенияработы

междупотоками:директиваsections

#include <stdio.h> #include <omp.h>

intmain(int argc,char*argv[])

{

intn=0;

#pragmaompparallel

{

#pragmaompsectionslastprivate(n)

{

142

Конструкциираспределенияработы

междупотоками:директиваsections

#pragmaompsection

{

n=1;

}

#pragmaompsection

{

n=2;

}

#pragmaompsection

{

n=3;

}

}

143

 

Конструкциираспределенияработы

междупотоками:директиваsections

printf("Значениеnнанити%d:%d\n", omp_get_thread_num(),n);

}

printf("Значениеnвпоследовательной области:%d\n",n);

}

144

Конструкциираспределенияработы

междупотоками:директиваmaster

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

145

Конструкциираспределенияработы

междупотоками:директиваmaster

#pragmaompmaster

Раздел(clause) — это необязательный модификатор директивы, влияющий на ее поведение. Списки разделов, поддерживаемые каждой директивой, различаются, а пять директив (master, critical,flush, ordered и atomic) вообще не поддерживают разделы.

146

Конструкциираспределенияработы

междупотоками:директиваmaster

Следующийпримердемонстрирует применениедирективыmaster. Переменнаяn являетсялокальной, тоесть каждая нитьработает сосвоим экземпляром.

147

Конструкциираспределенияработы

междупотоками:директиваmaster

Сначалавсенитиприсвоятпеременнойn значение1.Потом нить-мастерприсвоит переменнойnзначение2,ивсенити напечатаютзначениеn.

148

Конструкциираспределенияработы

междупотоками:директиваmaster

Затем нить-мастерприсвоитпеременнойn значение3,исновавсенитинапечатают значениеn.

149

Конструкциираспределенияработы

междупотоками:директиваmaster

Видно,чтодирективуmasterвсегда выполняетоднаитаженить.Вданном примеревсенитивыведутзначение1,а нить-мастерсначалавыведетзначение2, апотомзначение3.

150

Конструкциираспределенияработы между потоками: директиваmaster

#include <stdio.h>

int main(int argc, char *argv[])

{

int n;

#pragma omp parallel private(n)

{

n = 1;

#pragma omp master

{

n = 2;

}

printf("Первоезначениеn:%d\n",n);

151

Конструкциираспределенияработы

междупотоками:директиваmaster

#pragma omp barrier #pragma omp master

{

n=3;

}

printf("Второе значениеn:%d\n",n);

}

}

152

Конструкциисинхронизации:

директиваcritical

С помощью директив critical оформляется критическая секция программы.

#pragma omp critical имя[()]

структурированный блок

Критическая секция запрещает одновременное исполнение структурированного блока более чем одним потоком.

Конструкциисинхронизации:

директиваcritical

Следующий пример иллюстрирует применение директивы critical. Переменнаяn объявленавне параллельной области, поэтому по умолчанию является общей.Критическая секция позволяет разграничить доступ к переменной n. Каждая нить по очереди присвоит n свой номер и затем напечатает полученное значение.

Конструкциисинхронизации:

директиваcritical

#include <stdio.h> #include <omp.h>

int main(int argc, char *argv[])

{

int n;

#pragma omp parallel

{

#pragma omp critical

{

n = omp_get_thread_num(); printf("Нить %d\n", n);

}

}

}

Конструкциисинхронизации:

директиваbarrier

Самый распространенный способ синхронизации в OpenMP – барьер. Он оформляется с помощью директивы barrier.

#pragma omp barrier

Директива barrier дает всем потокам указание ожидать друг друга перед тем, как они продолжат выполнение за барьером.

Конструкциисинхронизации:

директиваbarrier

Нити, выполняющие текущую параллельную область, дойдя до этой директивы, останавливаютсяи ждут, пока все нити не дойдут до этой точки программы, после чего разблокируются и продолжают работать дальше. Кроме того, для разблокировки необходимо, чтобы все синхронизируемые нити завершили все порождённые ими задачи (task).

Конструкциисинхронизации:

директиваbarrier

Следующий пример демонстрирует применение директивы barrier. Директива barrier используется для упорядочивания вывода от работающих нитей. Выдачи с разных нитей "Сообщение 1"и "Сообщение 2“ могут чередоваться в произвольном порядке, а выдача "Сообщение 3« со всех нитей придёт строго после двух предыдущих выдач.

Конструкциисинхронизации:

директиваbarrier

#include <stdio.h> #include <omp.h>

intmain(intargc,char*argv[])

{

#pragmaompparallel

{

printf("Сообщение1\n"); printf("Сообщение2\n");

#pragmaompbarrier printf("Сообщение3\n");

}

}