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

Синхронизация

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

Синхронизация

Неявная барьерная синхронизация выполняется также в конце каждого блока #pragma omp for, #pragma omp single и #pragma omp sections. Чтобы отключить неявную барьерную синхронизацию в каком-либо из этих трех блоков разделения работы, нужно указать раздел nowait:

Пример

#pragmaompparallel

{

#pragmaompfornowait for(inti=1;i<size;++i) x[i]=(y[i-1]+y[i+1])/2;

}

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

162

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

директиваatomic

Частым случаем использования критических секций на практике является обновление общих переменных. Например, если переменнаяsum являетсяобщей и оператор вида sum = sum + expr находится в параллельной области программы, то при одновременном выполнении данного оператора несколькими нитями можно получить некорректный результат.

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

директиваatomic

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

#pragmaompatomic[read|write|update |capture]

оператор

или

#pragmaompatomiccapture

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

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

директиваatomic

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

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

директиваatomic

Навремявыполненияоператора блокируетсядоступ кданнойпеременной всемзапущеннымвданныймоментнитям, кроменити,выполняющейоперацию. Атомарной являетсятолько работас переменнойвлевойчастиоператора присваивания,приэтомвычисленияв правойчастинеобязаныбытьатомарными.

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

директиваatomic

Пример.

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

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

директиваatomic

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

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

{

int count = 0; #pragma omp parallel

{

#pragma omp atomic count++;

}

printf("Число нитей: %d\n", count);

}

Директиваordered

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

#pragmaompordered

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

Директиваordered

Блокоператоров относится ксамому внутреннемуизобъемлющихциклов,ав параллельном цикледолжнабытьзадана опцияordered.Нить,выполняющаяпервую итерациюцикла,выполняетоперации данногоблока.

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

директиваordered

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

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

директиваordered

Следующийпримериллюстрирует применениедирективыorderedиопции ordered.Циклforпомеченкакordered.

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

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

директиваordered

int i, n;

#pragma omp parallel private (i, n)

{

n = omp_get_thread_num(); #pragma omp for ordered

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

{

printf("Нить%d,итерация%d\n", n,i);

#pragma omp ordered

{

printf("ordered: Нить %d, итерация %d\n", n, i);

}

}

}

Директиваtask

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

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

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

Директиваtask

Текущаянитьвыделяетвкачествезадачи ассоциированныйсдирективойблок операторов. Задачаможетвыполняться немедленнопослесозданияилибыть отложенной нанеопределённоевремяи выполнятьсяпочастям.Размертаких частей,атакжепорядоквыполнениячастей разныхотложенныхзадачопределяется реализацией.

Директиваtask

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

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

Директиваtask

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

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

Директиваtask

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

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

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

директиваtask

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

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

Директиваtask

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

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

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

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

Вспомогательныефункции

ВOpenMP существуетряд вспомогательныхфункций

Дляихиспользованиянеобходимо подключитьзаголовочный файл:

#include <omp.h>

181

Функцииисполняющейсреды

Эти функциипозволяютзапрашиватьи задаватьразличныепараметрысреды

OpenMP:

omp_get_num_procsвозвращаетчисло вычислительныхузлов(процессоров/ядер) вкомпьютере.

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

182

Функцииисполняющейсреды

omp_get_num_threadsвозвращаетчисло потоков, входящихвтекущуюгруппу потоков.

omp_get_max_threadsвозвращает максимальнодопустимоечислонитейдля использованиявследующейпараллельной области.

183

Функцииисполняющейсреды

omp_set_num_threadзадаетчисло потоков длявыполненияследующего параллельного региона,который встретитсятекущемувыполняемому потоку.Функцияможетпомочь распределитьресурсы.

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

Функцииисполняющейсреды

omp_set_nestedразрешаетилизапрещает вложенныйпараллелизм.Есливложенный параллелизмразрешён,токаждая нить,в которой встретитсяописание параллельной области,породитдля её выполненияновуюгруппунитейистанетв нейглавной.

omp_get_nestedвозвращает,разрешенли вложенныйпараллелизмилинет.

185

Функцииисполняющейсреды

Еслиимяфункцииначинаетсясomp_set_,то ееможновызыватьтолько вне параллельныхрегионов.

Всеостальные функцииможноиспользовать как внутрипараллельныхрегионов,таки внетаковых.

186

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

Функциисинхронизации/блокировки

OpenMP позволяетстроить параллельныйкодбезиспользования этихфункций,таккакимеются директивы,позволяющие осуществлятьопределенныевиды синхронизации

Однаковрядеслучаевэти функции удобныидаженеобходимы

187

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

Функциисинхронизации/блокировки

ВOpenMP дватипаблокировок:простые ивложенные.

Вложенныеимеютсуффикс «nest»

Функция

omp_init_lock/omp_init_nest_l

ock omp_destroy_lock/omp_destr

oy_nest_lock omp_set_lock/omp_set_nest_

lock omp_unset_lock/omp_unset_

nest_lock omp_test_lock/omp_test_nest

_lock

Аналог

InitializeCriticalSection

DeleteCriticalSection

EnterCriticalSection

LeaveCriticalSection

TryEnterCriticalSection

188

Функциисинхронизации/блокировки

omp_init_lock — инициализация переменнойтипаomp_lock_t.Аналог

InitializeCriticalSection.

omp_destroy_lock — освобождение переменнойтипаomp_lock_t.Аналог

DeleteCriticalSection.

189

Функциисинхронизации/блокировки

omp_set_lock — одинпоток выставляет блокировку,аостальныепотоки ждут, покапоток, вызвавшаяэтуфункцию,не сниметблокировкуспомощьюфункции omp_unset_lock().Аналог EnterCriticalSection.

omp_unset_lock — снятиеблокировки.

Аналог LeaveCriticalSection.

190

Функциисинхронизации/блокировки

omp_test_lock — неблокирующая попытказахватазамка.Данная функция пробуетзахватить указанныйзамок.Если этоудалось,тодляпростого замка функциявозвращает1.Еслизамок захватить неудалось,то возвращается0.

АналогTryEnterCriticalSection.

191