программирования (tbb, openmp) · Модели многопоточного...
TRANSCRIPT
![Page 1: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/1.jpg)
Модели многопоточного программирования (TBB, OpenMP)
Алексей Федотов
SSG/DPD/TCAR/Threading Runtimes
22.02.2017
![Page 2: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/2.jpg)
Мотивация
“The free lunch is over: A Fundamental Turn Toward Concurrency” – Herb Sutter, Dr. Dobb’s журнал, март 2005 г.
2
10 ГГц
1 ГГц
100 МГц
10 МГц
1 МГц
’79 ’87 ’95 ’03 ’11
Частота процессора
больше
не возрастает
… но мы хотим, чтобы
приложения исполнялись
быстрее…
Когда нет супергероя, на помощь приходят миллионы рядовых солдат!
![Page 3: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/3.jpg)
Уровни параллелизма(аппаратное обеспечение)
• Параллелизм на уровне инструкций (ILP)• Конвейерное исполнение.
• Супер-скалярное исполнение (Hyper-Threading).
• Параллелизм на уровне данных (DLP)• SIMD (Single Instruction Multiple Data) векторная обработка.
• Реализован через использование SSE регистров и инструкций.
• Параллелизм на уровне потоков (TLP)• Многоядерная архитектура.
• Множество сокетов с когерентной кэш-памятью.
• Параллелизм на уровне кластеров (CLP)• Множество платформ, соединённых через сеть.
• Нет аппаратный поддержки когерентности кэш-памяти.
3
![Page 4: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/4.jpg)
Уровни параллелизма(программное обеспечение)
• Передача сообщений
• Обработка событий
• Параллелизм данных
• Вектора, SIMD
• Параллелизм данных
• Параллелизм задач
• Шаблон fork-join
Неструктурированный
Структурированный
Структурированный
Все 3 уровня необходимы чтобы достигнутьмаксимального параллелизма
4
![Page 5: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/5.jpg)
5
![Page 6: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/6.jpg)
void AddHead (struct List *list,
struct Node *node) {
node->next = list->head;
list->head = node;
}
Сработает на двух потоках?
6
![Page 7: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/7.jpg)
int flag = 0;
void AddHead (struct List *list,
struct Node *node) {
while (flag != 0) /* wait */ ;
flag = 1;
node->next = list->head;
list->head = node;
flag = 0;
}
Сработает на двух потоках?
7
T10
flagT2
1
flag
0
flag
![Page 8: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/8.jpg)
Гонки данных
Пример: i++;
8
Поток №1 Поток №2Общийсчётчик
0
Чтение 0
Сложение 0
Запись 1
Чтение 1
Сложение 1
Запись 2
Поток №1 Поток №2Общийсчётчик
0
Чтение 0
Чтение 0
Сложение 0
Сложение 0
Запись 1
Запись 1
![Page 9: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/9.jpg)
Чем гонки данных так неприятны?
Программы, в которых есть гонки данных, проявляютнедетерминированность в своём исполнении:
• Иногда дают верный результат
• Иногда дают ошибочный результат
Такие программы обычно работают корректно намаленьком количестве потоков с небольшим наборомданных.
Проблемы проявляются чаще, когда количествопотоков и время выполнения программы возрастает.
9
Отладка таких программ затруднительна!
![Page 10: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/10.jpg)
Критические секции
• Это участки кода, которые выполняются потоками эксклюзивно.
• Реализованы при помощи примитивов синхронизации:
• pthread_mutex (Linux*)
• CRITICAL_SECTION (Windows*)
10
Критические секции устраняют гонки данных!
Критические секции исполняются последовательно!
Нужно понять, что должно исполняться эксклюзивно!
![Page 11: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/11.jpg)
Взаимная блокировка
Потоки ждут некоторого события или условия, которое никогда не произойдёт.
Пример: дорожные пробки.Машины не могут повернуть или развернуться.
11
![Page 12: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/12.jpg)
12
Взаимная блокировка (пример)
CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2;
int x = 0;
int y = 0;
InitializeCriticalSection(&cs1); // Allocation Site (cs1)
InitializeCriticalSection(&cs2); // Allocation Site (cs2)
EnterCriticalSection(&cs1);
x++;
EnterCriticalSection(&cs2);
y++;
LeaveCriticalSection(&cs2);
LeaveCriticalSection(&cs1);
EnterCriticalSection(&cs2);
y++;
EnterCriticalSection(&cs1);
x++;
LeaveCriticalSection(&cs1);
LeaveCriticalSection(&cs2);
Поток №1 Поток №2
Нарушение порядка захвата
1. EnterCriticalSection(&cs1); в потоке №1
2. EnterCriticalSection(&cs2); в потоке №1
3. EnterCriticalSection(&cs2); в потоке №2
4. EnterCriticalSection(&cs1); в потоке №2
Взаимная блокировка
1. EnterCriticalSection(&cs1); в потоке №1
2. EnterCriticalSection(&cs2); в потоке №2
![Page 13: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/13.jpg)
13
Активная взаимная блокировка
http://stackoverflow.com/a/27997039/2882509
![Page 14: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/14.jpg)
Ложное разделение ресурсовнеумышленное разделение данных в кэш-линии
Условия:
Два или более потока «работают» с одной и той же кэш-линией, но с разными адресами в памяти.
Хотя бы один поток пишет в свой адрес памяти, фактически помечая кэш-линию на других ядрах как устаревшую.
Последствия:
При следующем обращении по своему адресу ядру будет необходимо обратиться к памяти снова, чтобы загрузить «свежие» данные из неё.
14
![Page 15: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/15.jpg)
float a[N], b[N];
float localSum[NUM_PROCS];
void* work(int tid) {
for (int j = 0; j < ITERATIONS; j++) {
for (int i = tid; i < N; i+= NUM_PROCS) {
a[i] = i + a[i] * b[i];
localSum[tid] += a[i];
}
}
}
0 1 2 3 4 … N-1a[i]
0 1 2 3 4 … N-1b[i]
thread 1 thread 2
0 1 2 3 4 … 15cacheline
Ложное разделение ресурсов (пример)
15
Пусть NUM_PROCS = 2:
![Page 16: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/16.jpg)
void* work(int tid) {
for (int j = 0; j < ITERATIONS; j++) {
for (int i = ;
i < ; i++)
{
a[i] = i + a[i] * b[i];
}
}
}
Ложное разделение ресурсов (пример)
16
int chunks = N / NUM_PROCS;
tid * chunks
(tid + 1) * chunks
float sum = 0.0f;
localSum[tid] += a[i];
localSum[tid] = sum;
sum += a[i];
![Page 17: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/17.jpg)
Шаблоны параллельных алгоритмов
![Page 18: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/18.jpg)
Шаблоны параллельных алгоритмов
18
![Page 19: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/19.jpg)
• Fork-join запускает исполнение нескольких задач одновременно и затем дожидается завершения каждой из них• Удобен в применении для
функциональной и рекурсивной декомпозиции• Используется как базовый
блок для построения других шаблонов
Примеры: Сортировка слиянием, быстрая сортировка (Хоара), другие алгоритмы «разделяй-и-властвуй»
Шаблон: Fork-Join
19
![Page 20: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/20.jpg)
Функциональная декомпозиция
20
int e;
main () {
int x[10], j, k, m; j = f(x, k); m = g(x, k);
...
}
int f(int *x, int k)
{
int a; a = e * x[k] * x[k]; return a;
}
int g(int *x, int k)
{
int a; k = k-1; a = e / x[k]; return a;
}
Поток №0
Поток №1
Статическая переменная: общаяГлобальная для потоков: общая
Локальные переменные функций
![Page 21: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/21.jpg)
Рекурсивный (вложенный) параллелизм
21
![Page 22: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/22.jpg)
Эффективная рекурсия с fork-join
•Легко «вкладывается»
•Накладные расходы делятся между потоками
Рекурсивный fork-join обеспечивает высокую степень параллелизма
22
![Page 23: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/23.jpg)
• Map применяет указанную функцию к каждому элементу из заданного набора• Это может быть некий
набор данных или абстрактный индекс
• В серийной программе это частный случай итерирования –независимые операции.
A = map(f)(B);
Примеры: цветовая коррекция изображений; преобразование координат; трассировка лучей; методы Монте-Карло
Шаблон: Map
23
![Page 24: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/24.jpg)
Параллелизм по данным
Последовательный код
24
for (int i = N/2; i < N; i++) a[i] = foo(i);
for (int i = 0; i < N/2; i++) a[i] = foo(i);
const int N = 1000;int a[N];for (int i = 0; i < N; i++) a[i] = foo(i);
Локальная памятьРазделяемая память
Поток №0
Поток №1
![Page 25: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/25.jpg)
Параллелизм по данным
25
Разделяемая
память
Поток №0 Поток №2
Поток №1
f ( )
f ( )
f ( )
![Page 26: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/26.jpg)
• Reduce объединяет, при помощи ассоциативной операции, все элементы набора в один элемент
• Например, reduce можно использовать, чтобы найти сумму элементов или максимальный элемент
b = reduce(f)(B);
Примеры: вычисление агрегатных функций; операции с матрицами; численное интегрирование
Шаблон: Reduce
26
![Page 27: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/27.jpg)
• Конвейер – цепочка из стадий обработки потока данных
• Некоторые стадии могут иметь состояние
• Можно обрабатывать данные по мере поступления: “online”
Примеры: сжатие/распаковка данных, обработка сигналов, фильтрация изображений
Шаблон: Pipeline
27
![Page 28: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/28.jpg)
Конвейер
Разные данные на разных стадиях
Разные данные в одной стадии, если там нет состояния
Данные на выходе могут быть переупорядочены
Может понадобиться буферизация между стадиями
28
![Page 29: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/29.jpg)
Bzip2: схема конвейера
Read block
Run-length encoding
Output stream
checksum
bit position
output file ptr
Burrows-Wheeler Transform
Move To Front
Run-length Encoding
Huffman Coding
Checksum
Bit-align
Write block
Input stream
input file ptr
29
![Page 30: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/30.jpg)
• Scan полезен в сценариях, когда данные по сути зависимы.
• Для достижения параллелизма необходимо слегка «извернуться».
• Необходимо, чтобы операция удовлетворяла правилу ассоциативности.
Примеры: вычисление частичных сумм, сортировка подсчётом, ранжирование списка, интегральные изображения
Шаблон: Scan
30
![Page 31: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/31.jpg)
31
int n = 16; int temp = 0;
for(int i = 0; i < n; ++i) {
y[i] = temp;
temp = temp + z[i];
}
y[n] = temp;
Задача: найти частичные суммы
1 2 3 4 5 166 7 8 9 10 11 12 13 14 15z[]
y[] 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105120136
![Page 32: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/32.jpg)
Реализация параллельныхпаттернов: OpenMP
Алексей Федотов, Михаил Дворский
SSG/DPD/TCAR/Threading Runtimes
22.02.2017
![Page 33: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/33.jpg)
33
OpenMP «в двух словах»
• Стандарт де-факто, OpenMP 4.0, с июля 2013 года
• API для C/C++ и Fortran для модели параллельногопрограммирования с разделяемой моделью памяти
• Базируется на директивах (pragmas в C/C++)
• Портируемость (есть для многих платформ)
• Поддержка различных типов параллелизма
![Page 34: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/34.jpg)
34
Явное выражение параллелизма
• Необходимо знание системного API.
• Дизайн и отладка задачи «выливаются» в программирование системных потоков.
Создание потоков…
Разбиение на подзадачи...
Синхронизация/ожидание...
Освобождение ресурсов...
![Page 35: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/35.jpg)
35
Явное выражение параллелизма (Win32)for(int i=0; i < nThread; ++i) // создание потоков
hThreads[i] = CreateThread(NULL, 0, ThreadFn, threadData, CREATE_SUSPENDED, NULL);
ParallelFor(); // параллельная работа
for(int i=0; i < nThread; ++i) // освобождение ресурсов
CloseHandle(hThreads[i]);
DWORD ThreadFn(void* passedInData) {
ThreadData *pData = (ThreadData *)passedInData;
for(int i = pData->begin; i < pData->end; ++i )
pData->x[i] = (pData->y[i-1] + pData->y[i+1]) / 2;
return 0;
}
void ParallelFor() {
for(int i=0; i < nThread; ++i) // Запуск потоков
ResumeThread(hThreads[i]);
WaitForMultipleObjects(nThread, hThreads, TRUE, INFINITE);
}
![Page 36: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/36.jpg)
36
Модель
Fork-join parallelism:
• Основной поток создаёт потоки по мере необходимости
• Параллелизм появляется в процессе исполнения: последовательная программа эволюционирует в параллельную
Параллельные регионы
Основной поток
![Page 37: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/37.jpg)
37
Конструкции OpenMP
OpenMP поддерживает следующие директивы:
parallel, for, parallel for, section, sections, single, master, critical, flush, ordered и atomic
#pragma omp <директива> [клауза [ [,] клауза]...]
Самая важная директива - parallel. Она создает параллельный регион для следующего за ней структурированного блока
#pragma omp parallel [клауза[ [,] клауза]...]
структурированный блок
Для реализации параллельного выполнения блоков приложения нужно просто добавить в код директивы pragma
![Page 38: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/38.jpg)
38
Параллельные регионы
Определяет параллельный регион над структурированным участком кода
Потоки создаются в тот месте кода, где стоит указание «parallel»
Потоки блокируются в конце региона
Данные становятся общими, если не специфицировано иное
#pragma omp parallel
Thread
1Thread
2Thread
3
C/C++ : #pragma omp parallel
{
block
}
![Page 39: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/39.jpg)
39
Конструкция «Распределение работы»
Потокам назначаются независимые итерации
Потоки ждут в конце
#pragma omp parallel
#pragma omp for
Implicit barrier
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
i = 11
#pragma omp parallel
#pragma omp for
for(i = 0; i < 12; i++)
c[i] = a[i] + b[i]
![Page 40: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/40.jpg)
40
Комбинирование директив
Следующие сегменты кода эквивалентны
#pragma omp parallel
{
#pragma omp for
for (i=0; i< MAX; i++) {
res[i] = huge();
}
}
#pragma omp parallel for
for (i=0; i< MAX; i++) {
res[i] = huge();
}
![Page 41: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/41.jpg)
41
Частные и общие и данные.
private. Порождает отдельную копию переменной для каждого потока. Переменные не инициализируются. С++ объекты конструируются по умолчанию. Значение переменных после параллельного региона неопределено.
firstprivate. Перед выполнением параллельного региона значение переменной основного потока копируется в каждый поток. Для С++ объектов используется конструктор копии.
lastprivate. При выполнении последней итерации параллельного цикла значение переменной, указанной в разделе lastprivate, присваивается переменной основного потока. Для С++ объектов используется оператор присваивания.
shared. Переменные «разделяются» между всеми потоками в параллельной секциии.
![Page 42: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/42.jpg)
42
Частные и общие данные. Примеры
float dot_prod(float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for(int i=0; i<N; i++) {
sum += a[i] * b[i];
}
return sum;
}
Всё ли верно?
void* work(float* c, int N) {
float x, y; int i;
#pragma omp parallel for private(x,y)
for(i=0; i<N; i++) {
x = a[i]; y = b[i];
c[i] = x + y;
}
}
![Page 43: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/43.jpg)
43
Директива critical
Ответственность за предоставление эксклюзивного доступа к разделяемой памяти лежит на пользователе:
float dot_prod(float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for(int i=0; i<N; i++) {
#pragma omp critical
sum += a[i] * b[i];
}
return sum;
}
![Page 44: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/44.jpg)
44
Директива atomic
• Применимо только для простых операций записи
• Вычисление левой и правой частей оператора “+=“ не атомарные (!)
float dot_prod(float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for(int i=0; i<N; i++) {
#pragma omp atomic
sum += a[i] * b[i];
}
return sum;
}
![Page 45: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/45.jpg)
45
Директива reduction
Локальная копия переменной sum у каждого потока
Локальные копии складываются вместе, и сохраняются в глобальной переменной
#pragma omp parallel for reduction(+:sum)
for(i=0; i<N; i++) {
sum += a[i] * b[i];
}
![Page 46: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/46.jpg)
46
Целый набор ассоциативных и коммутативных операций может быть использован с директивой редукции
Начальные значения те, которые имею смысл.
Oперации редукции (OpenMP 2.0)
Оператор Начальное значение
+ 0
* 1
- 0
^ 0
Оператор Начальное значение
& ~0
| 0
&& 1
|| 0
![Page 47: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/47.jpg)
47
Директива schedule
Когда следует использовать
staticПредсказуемое и схожее количество работы на каждой итерации
dynamicНепредсказуемое, высоко изменчивое количество работы на каждой итерации
guidedСпециальный случай динамического распределения. Призван сократить накладные расходы, связанные с самим распределением
auto Решение о распределении принимается компилятором
runtimeРаспределение задаётся переменной окружения OMP_SCHEDULE.
Распределение работы в цикле
![Page 48: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/48.jpg)
48
Пример использования директивы schedule
#pragma omp parallel for schedule (static, 8)
for( int i = start; i <= end; i += 2 )
{
if ( TestForPrime(i) ) foo(i);
}
• Итерации разделяются блоками по 8
• Если start = 3, то первый блок включает итерации 3, 5, 7, 9,11, 13, 15, 17
![Page 49: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/49.jpg)
49
Параллельные секции
Независимые секции кода могут исполняться одновременно
#pragma omp parallel sections
{
#pragma omp section
phase1();
#pragma omp section
phase2();
#pragma omp section
phase3();
}
![Page 50: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/50.jpg)
50
Обозначает блок кода, который исполнится только одним потоком
При этом не специфицируется каким именно
Неявный барьер в конце
Директива Single
#pragma omp parallel
{
DoManyThings();
#pragma omp single
{
ExchangeBoundaries();
} // threads wait here for single
DoManyMoreThings();
}
![Page 51: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/51.jpg)
51
Обозначает блок кода, который исполнится только основным потоком
Нет неявного барьера в конце
Директива Master
#pragma omp parallel
{
DoManyThings();
#pragma omp master
{ // if not master skip to next stmt
ExchangeBoundaries();
}
DoManyMoreThings();
}
![Page 52: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/52.jpg)
52
Неявные барьеры
Несколько OpenMP директив имеют неявные барьеры
parallel
for
single
sections
Излишние барьеры отрицательно сказываются на производительности
Ожидающие потоки не делают полезной работы!
Можно указать OpenMP не использовать неявные барьерыпри помощи клаузы nowait
![Page 53: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/53.jpg)
53
Клауза “nowait”
Используйте, когда потокам не требуется ожидания, например, между независимыми вычислениями
#pragma single nowait
{ [...] }
#pragma omp for nowait
for(...)
{...};
#pragma omp for schedule(dynamic,1) nowait
for(int i=0; i<n; i++)
a[i] = bigFunc1(i);
#pragma omp for schedule(dynamic,1)
for(int j=0; j<m; j++)
b[j] = bigFunc2(j);
![Page 54: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/54.jpg)
54
Директива “barrier”
Позволяет задать синхронизацию явно
Каждый поток ждёт пока «не придут» остальные
#pragma omp parallel shared (A, B, C)
{
DoSomeWork(A,B);
printf(“Processed A into B\n”);
#pragma omp barrier
DoSomeWork(B,C);
printf(“Processed B into C\n”);
}
![Page 55: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/55.jpg)
55
Уровни параллелизма
Task Parallelism / MessagPassing
forkjoin
SIMD SIMD SIMD
fork-join
SIMD SIMD
Fork-join
SIMD SIMD SIMD
OpenMP 2.0
#pragma omp for
OpenMP 4.0
#pragma omp simd
![Page 56: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/56.jpg)
56
Example (omp simd)float dot_product(float* a, float* b, int n) {
float sum = 0.0f;
#pragma omp simd reduction(+:sum)
for(int i=0; i<n; ++i)
sum += a[i] * b[i];
return sum;
}
4x floats
![Page 57: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/57.jpg)
OpenMP 3.0/4.0 (Основные моменты)
• Поддержка задач
• Поддержка акселераторов с помощью target директив
• Поддержка SIMD директив для векторизации
• Поддержка зависимости между задачами (одного уровня), приоритеты задач
• Поддержка пользовательской редукции
• Явная «привязка» потоков к «железу»
• Обработка ошибок
• Поддержка Fortran 2003
57
![Page 58: программирования (TBB, OpenMP) · Модели многопоточного программирования (TBB, OpenMP) Алексей Федотов SSG/DPD/TCAR/Threading](https://reader036.vdocuments.net/reader036/viewer/2022071019/5fd2d322bf8c65647b5059ff/html5/thumbnails/58.jpg)