ОСНОВЫ ПОДХОДА
Технология OpenMP для систем с общей памятью
Способы разработки программ для параллельных вычислений…
Способы разработки программ для параллельных вычислений…
Способы разработки программ для параллельных вычислений
Принципы организации параллелизма…
Принципы организации параллелизма
Структура OpenMP
Директивы openmp
Формат записи директив…
Области видимости директив
Типы директив
Определение параллельной области
Формат директивы
Пример использования директивы…
Пример использования директивы
Установка количества потоков
Определение времени выполнения параллельной программы
Директивы openmp
Директивы управления областью видимости
Параметр shared
Параметр private
Пример использования директивы private
Параметр firstprivate
Параметр lastprivate
Директивы openmp
Директивы распределения вычислений между потоками
Директива for
Пример использования директивы for
Директива for. Параметр schedule
Пример использования директивы for
Директива sections…
Директива sections
Пример использования директивы sections…
Пример использования директивы sections
Объединение директив parallel и for/sections
Директивы openmp
Параметр reduction
Пример использования параметра reduction
Правила записи параметра reduction
Заключение
Литература
1.31M
Category: programmingprogramming

Параллельное программирование с использованием OpenMP. Лекция 1

1.

НИЖЕГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
им. Н.И. Лобачевского
- Национальный исследовательский университет -

2.

Нижегородский государственный университет им. Н.И. Лобачевского
– Национальный исследовательский университет –
Параллельное программирование
с использованием OpenMP
Гергель В.П.
д.т.н, проф., декан факультета ВМК,
руководитель Центра
суперкомпьютерных технологий ННГУ

3. ОСНОВЫ ПОДХОДА

Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
3 из 44

4. Технология OpenMP для систем с общей памятью

Технология OpenMP задумана как стандарт параллельного
программирования для многопроцессорных систем с общей
памятью (SMP, ccNUMA, …).
Процессор
Ядро
Процессор
Ядро
Ядро
Кэш
Ядро
Кэш
Оперативная
память
Н. Новгород, ННГУ, 2014 г.
Системы с общей памятью
описываются в виде модели
параллельного компьютера с
произвольным доступом к памяти
(parallel random-access machine –
PRAM).
Параллельное программирование с использованием OpenMP
4 из 44

5. Способы разработки программ для параллельных вычислений…

Способ 1: автоматическое распараллеливание
последовательных программ.
– возможности автоматического построения параллельных
программ ограничены.
Способ 2: расширение существующих алгоритмических
языков средствами параллельного программирования.
Способ 3: использование новых алгоритмических языков
параллельного программирования.
Примечание: Способы 2-3 приводят к необходимости
значительной переработки существующего программного
обеспечения.
.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
5 из 44

6. Способы разработки программ для параллельных вычислений…

Способ 4: использование тех или иных внеязыковых
средств языка программирования.
– Примеры средств – директивы или комментарии, которые
обрабатываются специальным препроцессором до начала
компиляции программы.
– Директивы дают указания на возможные способы
распараллеливания программы, при этом исходный
текст программы остается неизменным.
– Препроцессор заменяет директивы параллелизма на
дополнительный программный код (как правило, в виде
обращений к процедурам параллельной библиотеки).
– При отсутствии препроцессора компилятор построит
исходный последовательный программный код.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
6 из 44

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

Способ 4: Положительные стороны:
– Снижает потребность переработки
существующего программного кода.
– Обеспечивает единство программного кода для
последовательных и параллельных вычислений,
что снижает сложность развития и сопровождения
программ.
– Позволяет осуществлять поэтапную
(инкрементную) разработку параллельных
программ.
Именно этот подход и является основой
технологии OpenMP
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
7 из 44

8. Принципы организации параллелизма…

Использование потоков (общее адресное пространство).
«Пульсирующий» (fork-join) параллелизм.
*Источник: http://en.wikipedia.org/wiki/OpenMP
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
8 из 44

9. Принципы организации параллелизма

При выполнении обычного кода (вне параллельных
областей) программа исполняется одним потоком
(master thread).
При появлении директивы parallel происходит
создание “команды” (team) потоков для параллельного
выполнения вычислений.
После выхода из области действия директивы parallel
происходит синхронизация, все потоки, кроме master,
уничтожаются (или приостанавливаются).
Продолжается последовательное выполнение кода (до
очередного появления директивы parallel).
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
9 из 44

10. Структура OpenMP

Компоненты:
– Набор директив компилятора.
– Библиотека функций.
– Набор переменных окружения.
Изложение материала будет проводиться на примере
языка C/C++.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
10 из 44

11. Директивы openmp

ДИРЕКТИВЫ OPENMP
Формат, области видимости, типы.
Директива определения параллельной области.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
11 из 44

12. Формат записи директив…

Формат:
#pragma omp имя_директивы [параметр,…]
Пример:
#pragma omp parallel default(shared) private(beta,pi)
Примечание: На английском языке для термина «параметр»
используется обозначение «clause».
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
12 из 44

13. Области видимости директив

node.cpp
root.cpp
#pragma omp parallel
{
TypeThreadNum();
}
Статический
(лексический)
контекст
параллельной
области – блок,
следующий за
директивой
parallel.
Н. Новгород, ННГУ, 2014 г.
+
void TypeThreadNum() {
int num;
num = omp_get_thread_num();
#pragma omp critical
printf("Hello from %d\n",num);
}
Динамический
контекст
параллельной области
(включает статический
контекст) – все
функции из блока
parallel.
Отделяемые (orphaned)
директивы – директивы
синхронизации и
распределения работы.
Могут появляться вне
параллельной области.
Параллельное программирование с использованием OpenMP
13 из 44

14. Типы директив

Определение параллельной области.
Разделение работы.
Синхронизация.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
14 из 44

15. Определение параллельной области

Директива parallel (основная директива OpenMP):
– Когда основной поток выполнения достигает директиву
parallel , создается набор (team) потоков.
– Входной поток является основным потоком (master
thread) этого набора и имеет номер 0.
– Код области дублируется или разделяется между
потоками для параллельного выполнения.
– В конце области обеспечивается синхронизация
потоков – выполняется ожидание завершения
вычислений всех потоков.
– Далее все потоки завершаются, и последующие
вычисления продолжает выполнять только основной
поток.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
15 из 44

16. Формат директивы

Формат директивы parallel :
#pragma omp parallel [clause ...]
structured_block
Возможные параметры (clauses):
if (scalar_expression)
private (list)
firstprivate (list)
default (shared | none)
shared (list)
copyin (list)
reduction (operator: list)
num_threads(integer-expression)
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
16 из 44

17. Пример использования директивы…

#include <omp.h>
void main() {
int nthreads, tid;
// Создание параллельной области
#pragma omp parallel private(tid)
{
// печать номера потока
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
// Печать количества потоков – только master
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} // Завершение параллельной области
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
17 из 44

18. Пример использования директивы

Пример результатов выполнения программы для четырех
потоков
Hello
Hello
Hello
Hello
World
World
World
World
from
from
from
from
thread
thread
thread
thread
=
=
=
=
1
3
0
2
Примечание: Порядок печати потоков может меняться от
запуска к запуску!!!
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
18 из 44

19. Установка количества потоков

Способы задания (по убыванию старшинства)
– Параметр директивы:
num_threads(N)
– Функция установки числа потоков:
omp_set_num_threads(N)
– Переменная окружения:
OMP_NUM_THREADS
– Число, равное количеству процессоров, которое
“видит” операционная система.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
19 из 44

20. Определение времени выполнения параллельной программы

double t1, t2, dt;
t1 = omp_get_wtime ();

t2 = omp_get_wtime ();
dt = t2 – t1;
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
20 из 44

21. Директивы openmp

ДИРЕКТИВЫ OPENMP
Управление областью видимости данных.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
21 из 44

22. Директивы управления областью видимости

Управление областью видимости обеспечивается при
помощи параметров (clauses) директив:
– shared, default
– private
– firstprivate
– lastprivate
– reduction, copyin.
Параметры директив определяют, какие соотношения
существуют между переменными последовательных и
параллельных фрагментов выполняемой программы.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
22 из 44

23. Параметр shared

Параметр shared определяет список переменных,
которые будут общими для всех потоков параллельной
области.
#pragma omp parallel shared(list)
Примечание: правильность использования таких
переменных должна обеспечиваться программистом.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
23 из 44

24. Параметр private

Параметр private определяет список переменных,
которые будут локальными для каждого потока.
#pragma omp parallel private(list)
Переменные создаются в момент формирования потоков
параллельной области.
Начальное значение переменных является
неопределенным.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
24 из 44

25. Пример использования директивы private

#include <omp.h>
void main () {
int nthreads, tid;
// Создание параллельной области
#pragma omp parallel private(tid)
{
// печать номера потока
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
// Печать количества потоков – только master
if (tid == 0) {
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} // Завершение параллельной области
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
25 из 44

26. Параметр firstprivate

Параметр firstprivate позволяет создать локальные
переменные потоков, которые перед использованием
инициализируются значениями исходных переменных.
#pragma omp parallel firstprivate(list)
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
26 из 44

27. Параметр lastprivate

Параметр lastprivate позволяет создать локальные
переменные потоков, значения которых запоминаются в
исходных переменных после завершения параллельной
области (используются значения потока, выполнившего
последнюю итерацию цикла или последнюю секцию).
#pragma omp parallel lastprivate(list)
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
27 из 44

28. Директивы openmp

ДИРЕКТИВЫ OPENMP
Распределение вычислений между потоками
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
28 из 44

29. Директивы распределения вычислений между потоками

Существует 3 директивы для распределения вычислений
в параллельной области:
– for – распараллеливание циклов.
– sections – распараллеливание раздельных
фрагментов кода (функциональное
распараллеливание).
– single – директива для указания последовательного
выполнения кода.
Начало выполнения директив по умолчанию не
синхронизируется.
Завершение директив по умолчанию является
синхронным.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
29 из 44

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

Формат директивы for:
#pragma omp for [clause ...]
for loop
Возможные параметры (clause):
– private(list)
– firstprivate(list)
– lastprivate(list)
– schedule(kind[, chunk_size])
– reduction(operator: list)
– ordered
– nowait
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
30 из 44

31. Пример использования директивы for

#include <omp.h>
#define CHUNK 100
#define NMAX 1000
void main() {
int i, n, chunk;
float a[NMAX], b[NMAX], c[NMAX];
for (i=0; i < NMAX; i++)
a[i] = b[i] = i * 1.0;
n = NMAX; chunk = CHUNK;
#pragma omp parallel shared(a,b,c,n,chunk) private(i)
{
#pragma omp for
for (i=0; i < n; i++)
c[i] = a[i] + b[i];
} // end of parallel section
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
31 из 44

32. Директива for. Параметр schedule

static – итерации делятся на блоки по chunk итераций
и статически разделяются между потоками.
– Если параметр chunk не определен, итерации делятся
между потоками равномерно и непрерывно.
dynamic – распределение итерационных блоков
осуществляется динамически (по умолчанию chunk=1).
guided – размер итерационного блока уменьшается
экспоненциально при каждом распределении.
– chunk определяет минимальный размер блока (по
умолчанию chunk=1).
runtime – правило распределения определяется
переменной OMP_SCHEDULE (при использовании runtime
параметр chunk задаваться не должен).
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
32 из 44

33. Пример использования директивы for

#include <omp.h>
#define CHUNK 100
#define NMAX 1000
void main() {
int i, n, chunk;
float a[NMAX], b[NMAX], c[NMAX];
for (i=0; i < NMAX; i++)
a[i] = b[i] = i * 1.0;
n = NMAX; chunk = CHUNK;
#pragma omp parallel shared(a,b,c,n,chunk) private(i)
{
#pragma omp for schedule(dynamic,chunk)
for (i=0; i < n; i++)
c[i] = a[i] + b[i];
} // end of parallel section
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
33 из 44

34. Директива sections…

Формат директивы sections:
#pragma omp sections [clause ...]
{
#pragma omp section // несколько секций
structured_block
}
Возможные параметры (clause):
– private(list),
– firstprivate(list),
– lastprivate(list),
– reduction(operator: list),
– nowait
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
34 из 44

35. Директива sections

Директива sections – распределение вычислений для
раздельных фрагментов кода.
Фрагменты кода:
– Выделяются при помощи директивы section.
– Каждый фрагмент выполняется однократно.
– Разные фрагменты выполняются разными потоками.
– Завершение директивы по умолчанию
синхронизируется
– Директивы section должны использоваться только в
статическом контексте.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
35 из 44

36. Пример использования директивы sections…

#include <omp.h>
#define NMAX 1000
void main() {
int i, n;
float a[NMAX], b[NMAX], c[NMAX];
for (i=0; i < NMAX; i++)
a[i] = b[i] = i * 1.0;
n = NMAX;
#pragma omp parallel shared(a,b,c,n) private(i)
{
// продолжение на следующем слайде
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
36 из 44

37. Пример использования директивы sections

#pragma omp sections nowait
{
#pragma omp section
for (i=0; i < n/2; i++)
c[i] = a[i] + b[i];
#pragma omp section
for (i=n/2; i < n; i++)
c[i] = a[i] + b[i];
} // end of sections
} // end of parallel section
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
37 из 44

38. Объединение директив parallel и for/sections

#include <omp.h>
#define CHUNK 100
#define NMAX 1000
void main () {
int i, n, chunk;
float a[NMAX], b[NMAX], c[NMAX];
for (i=0; i < NMAX; i++)
a[i] = b[i] = i * 1.0;
n = NMAX;
chunk = CHUNK;
#pragma omp parallel for shared(a,b,c,n) \
schedule(static,chunk)
for (i=0; i < n; i++)
c[i] = a[i] + b[i];
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
38 из 44

39. Директивы openmp

ДИРЕКТИВЫ OPENMP
Операция редукции
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
39 из 44

40. Параметр reduction

Параметр reduction определяет список переменных,
для которых выполняется операция редукции
(объединения).
reduction (operator: list)
Перед выполнением параллельной области для каждого
потока создаются копии этих переменных.
Потоки формируют значения в своих локальных
переменных.
При завершении параллельной области на всеми
локальными значениями выполняются необходимые
операции редукции, результаты которых запоминаются в
исходных (глобальных) переменных.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
40 из 44

41. Пример использования параметра reduction

#include <omp.h>
void main() { // vector dot product
int i, n, chunk;
float a[100], b[100], result;
n = 100; chunk = 10;
result = 0.0;
for (i=0; i < n; i++) {
a[i] = i * 1.0; b[i] = i * 2.0;
}
#pragma omp parallel for default(shared) \
schedule(static,chunk) reduction(+:result)
for (i=0; i < n; i++)
result = result + (a[i] * b[i]);
printf("Final result= %f\n",result);
}
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
41 из 44

42. Правила записи параметра reduction

Возможный формат записи выражения:
– x = x op expr
– x = expr op x
– x binop = expr
– x++, ++x, x--, --x
x должна быть скалярной переменной.
expr не должно ссылаться на x.
op (operator) должна быть неперегруженной операцией
вида:
+, -, *, /, &, ^, |, &&, ||
binop должна быть неперегруженной операцией вида:
+, -, *, /, &, ^, |
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
42 из 44

43. Заключение

Данная лекция посвящена рассмотрению методов
параллельного программирования для вычислительных
систем с общей памятью с использованием технологии
OpenMP.
В лекции проводится обзор технологии OpenMP.
Рассматриваются директивы OpenMP, позволяющие
– определять параллельные области,
– управлять областью видимости данных,
– распределять вычислений между потоками,
– выполнять операции редукции.
Дальнейшее изучение технологии OpenMP будет
продолжено в одной из следующих лекций.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
43 из 44

44. Литература

Гергель В.П. Высокопроизводительные вычисления для
многопроцессорных многоядерных систем. - М.: Изд-во
Московского университета, 2010. – 544 с.
Дополнительная литература:
– Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. –
СПб.: БХВ-Петербург, 2002.
– Гергель В.П. Теория и практика параллельных вычислений. - М.:
Интернет-Университет, БИНОМ. Лаборатория знаний, 2007.
– Гергель В.П. Новые языки и технологии параллельного
программирования. - М.: Издательство Московского университета,
2012. – 434 с.
– Гергель В.П., Баркалов К.А., Мееров И.Б., Сысоев А.В. и др.
Параллельные вычисления. Технологии и численные методы.
Учебное пособие в 4 томах. – Нижний Новгород: Изд-во
Нижегородского госуниверситета, 2013. – 1394 с.
Н. Новгород, ННГУ, 2014 г.
Параллельное программирование с использованием OpenMP
44 из 44
English     Русский Rules