Презентация на тему: Введение в технологию OpenMP

Реклама. Продолжение ниже
Введение в технологию OpenMP
Технология OpenMP
OpenMP : последовательные и параллельные секции
OpenMP: общие и локальные переменные
Модель OpenMP
OpenMP: Описание параллельных областей (1)
OpenMP: Описание параллельных областей (2)
Пример: применение директивы parallel
Пример: функция omp_set_num_threads(); опция num_threads
Пример: применение опции reduction
Open MP: Параллелизм на линейных участках программы
Open MP: распараллеливание операторов цикла
Open MP: синхронизация нитей (1)
Open MP: синхронизация нитей (2)
Open MP: синхронизация нитей (3)
Open MP: плюсы и минусы
Open MP: плюсы и минусы
1/17
Средняя оценка: 4.2/5 (всего оценок: 51)
Код скопирован в буфер обмена
Скачать (305 Кб)
Реклама. Продолжение ниже
1

Первый слайд презентации: Введение в технологию OpenMP

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

Изображение слайда
1/1
2

Слайд 2: Технология OpenMP

Одно из наиболее популярных средств программирования компьютеров с общей памятью (в том числе многоядерных ПК). Базируется на традиционных языках программирования и использовании специальных псевдокомментариев. Реализован привлекательный с точки зрения пользователя подход к распараллеливанию: проблема возлагается на компилятор, а пользователь только выдает компилятору ценные указания : «вот это можно исполнить параллельно, а вот это – нельзя!» Ценные указания оформляются как псевдокомментарии в тексте программы. За основу берется последовательная программа, а для создания ее параллельной версии пользователю предоставляется набор директив, процедур и переменных окружения. Стандарт OpenMP разработан для языков Фортран, С и С++. Все основные конструкции для этих языков похожи. OpenMP работает в системах с общей памятью и основан на понятии «легковесного процесса» или нити (thread).

Изображение слайда
1/1
3

Слайд 3: OpenMP : последовательные и параллельные секции

Весь текст программы разбит на последовательные и параллельные области. В начальный момент времени порождается нить-мастер ( master thread ), которая начинает выполнение программы со стартовой точки. Основная нить и только она исполняет все последовательные области программы. Для поддержки параллелизма используется схема Fork / Join (ветвление\объединение). При входе в параллельную область порождаются дополнительные нити ( Fork ). После порождения каждая нить получает свой уникальный номер, причем нить-мастер всегда имеет номер 0. Все нити исполняют один и тот же код, соответствующий параллельной области. При выходе из параллельной области основная нить дожидается завершения остальных нитей, и дальнейшее выполнение программы продолжает только она ( Join ).

Изображение слайда
Изображение для работы со слайдом
1/2
4

Слайд 4: OpenMP: общие и локальные переменные

В параллельной области все переменные программы разделяются на два класса: общие (SHARED) и локальные (PRIVATE). Общая переменная всегда существует лишь в одном экземпляре для всей программы и доступна всем нитям под одним и тем же именем. Объявление локальной переменной вызывает порождение своего экземпляра данной переменной для каждой нити. Изменение нитью значения своей локальной переменной, естественно, никак не влияет на изменение значения этой же локальной переменной в других нитях. Можно указать, что по умолчанию (default) тип будет private Firstprivate: присутствуют в последовательной части кода, предшествующей параллельной секции. В параллельной секции это значение присваивается локальным переменным с тем же именем в каждой нити. Lastprivate: после завершения блока переменная сохраняет значение, полученное в завершившемся самым последним парараллельном потоке

Изображение слайда
1/1
5

Слайд 5: Модель OpenMP

Рассмотренные два понятия: области и классы переменных, – определяют идею написания параллельной программы в рамках OpenMP: некоторые фрагменты текста программы объявляется параллельными областями; именно эти области, и только они, исполняются набором нитей, которые могут работать как с общими, так и с локальными переменными. Число нитей определяется системой. Его можно поменять «снаружи» export OMP_NUM_THREADS=256 В некоторых версиях поддерживаются функции, с помощью которых можно поменять число нитей «изнутри» Возможны вложенные параллельные секции. В зависимости от реализации – тоже можно поменять ( OMP_NESTED) Фортран: директивы OpenMP располагаются в комментариях и начинаются с одной из комбинаций: !$OMP, C$OMP или *$OMP. С\С++: используются директивы прагмы # pragma OMP.

Изображение слайда
1/1
6

Слайд 6: OpenMP: Описание параллельных областей (1)

Выделение параллельного блока программы: # pragma OMP parallel [описание переменных] { структурный блок программы} Для выполнения кода в фигурными скобках, порождается OMP_NUM_THREADS-1 нитей. Процесс, выполнивший директиву PARALLEL (нить-мастер), всегда получает номер 0. OMP_NUM_THREADS – переменная окружения, определяющая количество потоков (нитей) в параллельной программе. Все нити исполняют код параллельной секции, после чего автоматически происходит неявная синхронизация всех нитей. Как только все нити доходят до этой точки, нить-мастер продолжает выполнение последующей части программы, а остальные нити уничтожаются.

Изображение слайда
1/1
7

Слайд 7: OpenMP: Описание параллельных областей (2)

Функция OMP_GET_THREAD_NUM возвращает номер нити. Функция OMP_GET_NUM_THREADS возвращает кол-во нитей. Функция OMP_SET_NUM_THREAD устанавливает кол-во нитей. Необходимость порождения нитей может определяться динамически с помощью опции IF в директиве OMP PARALLEL IF( <условие> ) Пример. Ветвление в зависимости от номера параллельного потока. #pragma omp parallel { myid = omp_get_thread_num ( ); If (myid == 0) do_something ( ); else do_something_else ( ); }

Изображение слайда
1/1
Реклама. Продолжение ниже
8

Слайд 8: Пример: применение директивы parallel

#include <stdio.h> int main(int argc, char *argv[]) { printf(" Последовательная область 1\n"); #pragma omp parallel { printf("Параллельная область\n"); } printf(" Последовательная область 2\n"); } В результате выполнения нить-мастер напечатает текст « " Последовательная область 1» Далее по директиве parallel порождаются новые нити, каждая из которых напечатает текст « Параллельная область » ( OMP_NUM_THREADS раз). Затем порождённые нити завершаются и оставшаяся нить-мастер напечатает текст «Последовательная область 2».

Изображение слайда
1/1
9

Слайд 9: Пример: функция omp set num threads(); опция num threads

#include <stdio.h> #include <omp.h> int main(int argc, char *argv[]) { omp_set_num_threads(2); #pragma omp parallel num_threads(3) { printf(" Параллельная область 1\n"); } #pragma omp parallel { printf(" Параллельная область 2\n"); } Перед 1ой параллельной областью вызов omp_set_num_threads(2) выставляет кол-во нитей, равное 2. НО! к ней применяется опция num_threads(3), поэтому сообщение " Параллельная область 1 " напечатают три нити. К 2ой параллельной области опция num_threads не применяется, поэтому действует значение, установленное omp_set_num_threads(2). Поэтому сообщение " Параллельная область 2" будет выведено двумя нитями.

Изображение слайда
1/1
10

Слайд 10: Пример: применение опции reduction

Подсчет общего количества порождённых нитей. #include <stdio.h> int main(int argc, char *argv[]) { int count = 0; #pragma omp parallel reduction (+: count) { count++; printf(" Текущее значение count: %d\n",count); } printf(" Число нитей : %d\n", count); } Каждая нить инициализирует локальную копию переменной count = 0. Далее, каждая нить увеличивает значение своей копии переменной count на 1 и выводит полученное число. На выходе из параллельной области происходит суммирование значений переменных count по всем нитям. Полученная величина становится новым значением переменной count в последовательной области.

Изображение слайда
1/1
11

Слайд 11: Open MP: Параллелизм на линейных участках программы

Программирование на низком уровне : распределение работы с помощью функций OMP_GET_THREAD_NUM и OMP_GET_NUM_THREADS, возвращающих номер нити и общее кол-во порожденных нитей. Пример: if ( OMP_GET_THREAD_NUM() ==3 ) < код для нити с номером 3 > ; else < код для всех остальных нитей > ; Параллелизм на уровне независимых фрагментов : оформляется с помощью директивы SECTIONS: # pragma omp sections [… [parameters…] ] { #pragma omp section < фрагмент 1> #pragma omp section < фрагмент 2> } два фрагмента информационно независимы, и их можно исполнять в любом порядке, в частности, параллельно друг другу. Каждый из таких фрагментов будет выполнен какой-либо одной нитью.

Изображение слайда
1/1
12

Слайд 12: Open MP: распараллеливание операторов цикла

Если в параллельной области встретился оператор цикла, каждая нить выполнит все итерации данного цикла. Для распределения итераций цикла между различными нитями нужно использовать директивы !$OMP DO (фортран) и #pragma omp for (C\C++), которые относятся к идущему следом оператору цикла. Пример: #pragma omp parallel shared (a,b) private (j) { #pragma omp for for (j=0; j<N; J++) а [j] = a[j]+b[j] } По умолчанию в конце цикла реализуется барьерная синхронизация, которую можно отменить с помощью опции nowait

Изображение слайда
1/1
13

Слайд 13: Open MP: синхронизация нитей (1)

Директива SINGLE используется для однократного выполнения части кода, е сли в параллельной секции какой-то участок кода должен быть выполнен лишь один раз. # pragma omp single { } Такой участок кода будет выполнен (единожды) нитью, первой дошедшей до данной точки программы. Барьер оформляется с помощью директивы #pragma omp barrier Все нити, дойдя до этой директивы, останавливаются и ждут пока остальные нити не дойдут до этой точки программы, после чего все нити продолжают работать дальше. Директива MASTER выделяет участок кода, который должен быть выполнен только нитью-мастером. #pragma omp master { структурный блок программы} Остальные нити пропускают данный участок.

Изображение слайда
Изображение для работы со слайдом
1/2
14

Слайд 14: Open MP: синхронизация нитей (2)

Критическая секция оформляется с помощью директивы # pragma omp critical [ name ] { структурный блок программы} В каждый момент времени в критической секции может находиться не более одной нити. Если критическая секция уже выполняется какой-либо нитью, то все другие нити, выполнившие директиву для секции с данным именем, будут заблокированы, пока указанная нить не закончит выполнение данной критической секции. Как только нить закончит выполнение критической секции, одна из заблокированных на входе нитей войдет в секцию. Если на входе в критическую секцию стояло несколько нитей, то случайным образом выбирается одна из них, а остальные заблокированные нити продолжают ожидание. Директива atomic относится к идущему непосредственно за ней оператору. Частый случай использования критических секций. Пример: #pragma omp atomic Expr ++;.

Изображение слайда
Изображение для работы со слайдом
1/2
Реклама. Продолжение ниже
15

Слайд 15: Open MP: синхронизация нитей (3)

Согласование памяти. Синхронизация этого типа используется для обновления локальных переменных в оперативной памяти. Поскольку в современных параллельных вычислительных системах может использоваться сложная структура и иерархия памяти, пользователь должен иметь гарантии того, что в необходимые ему моменты времени каждая нить будет видеть единый согласованный образ памяти. Именно для этих целей и предназначена данная директива; # pragma omp flush ( var 1, [ var 2,…]) Ее выполнение предполагает, что значения всех переменных, временно хранящиеся в регистрах, будут занесены в основную память, все изменения переменных, сделанные нитями во время их работы, станут видимыми остальным нитям, если какая-то информация хранится в буферах вывода, то буферы будут сброшены и т.п. Таким образом, после выполнения данной директивы все перечисленные в ней переменные имеют одно и то же значение для всех параллельных потоков. Выполнение данной директивы в полном объеме может повлечь значительные накладные расходы.

Изображение слайда
Изображение для работы со слайдом
Изображение для работы со слайдом
1/3
16

Слайд 16: Open MP: плюсы и минусы

Технология изначально спроектирована, чтобы пользователь мог работать с единым текстом для параллельной и последовательной программ. Обычный компилятор на последовательной машине директивы O pen MP просто «не замечает». Другое достоинство O pen MP – возможность постепенного распараллели-вания программы. Взяв за основу последовательный код, пользователь step-by-step добавляет новые директивы, описывающие новые параллельные секции. Тем самым, упрощается процесс создания кода. С другой стороны, для ускорения вычислений необходимо, чтобы трудоемкость параллельных процессов существенно превосходила бы трудоемкость порождения потоков. Операции синхронизации и инициализации параллельных потоков эквивалентны примерно трудоемкости выполнения 1000 арифметических операций. Поэтому при выделении параллельных областей и разработке параллельных процессов необходимо, чтобы их трудоемкость была не менее 2000 операций. Важно следить за согласованием памяти! Возможность data race

Изображение слайда
1/1
17

Последний слайд презентации: Введение в технологию OpenMP: Open MP: плюсы и минусы

Эффект состязательности ( race condition). Результат зависит от того, в какой последовательности выполняются параллельные потоки. Поскольку синхронизации нет, каждый раз будет разный результат. При этом компилятор не выдает никакой диагностики. #pragma omp sections { # pragma omp section {C=A+B;} #pragma omp section {B=C+A;} #pragma omp section {A=B+C;} } Предполагается, что А,В,С – глобальные переменные ( shared). Компиляция на JINR- кластере : icc –openmp name.c

Изображение слайда
1/1
Реклама. Продолжение ниже