113
Обзор библиотеки Intel® Threading Building Blocks Алексей Федотов SSG/DPD/TCAR/Threading Runtimes

Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Обзор библиотекиIntel® Threading Building Blocks

Алексей Федотов

SSG/DPD/TCAR/Threading Runtimes

Page 2: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Intel® Threading Building Blocks (Intel® TBB) - это простойспособ помочь вашей программе эффективно использоватьвычислительные ресурсы системы, на которой онавыполняется.

Для чего нужна данная библиотека?

Время

ЗадачаУти

ли

зац

ия

си

сте

мы

Время

Задача

Ути

ли

зац

ия

си

сте

мы

2

Page 3: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

А что, без Intel® TBB неэффективно?

“The free lunch is over: A Fundamental Turn Toward Concurrency” – Herb Sutter, Dr. Dobb’s журнал, март 2005 г.

10 ГГц

1 ГГц

100 МГц

10 МГц

1 МГц

’79 ’87 ’95 ’03 ’11

Частота процессора

больше

не возрастает

… но мы хотим, чтобы

приложения исполнялись

быстрее…

Когда нет супергероя, на помощь приходят миллионы рядовых солдат!

3

Page 4: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Уровни параллелизма(аппаратное обеспечение)

• Параллелизм на уровне инструкций (ILP)• Конвейерное исполнение.

• Супер-скалярное исполнение (Hyper-Threading).

• Параллелизм на уровне данных (DLP)• SIMD (Single Instruction Multiple Data) векторная обработка.

• Реализован через использование SSE регистров и инструкций.

• Параллелизм на уровне потоков (TLP)• Многоядерная архитектура.

• Множество сокетов с когерентной кэш-памятью.

• Параллелизм на уровне кластеров (CLP)• Множество платформ, соединённых через сеть.

• Нет аппаратный поддержки когерентности кэш-памяти.

4

Page 5: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Уровни параллелизма(программное обеспечение)

• Передача сообщений

• Обработка событий

• Параллелизм данных

• Вектора, SIMD

• Параллелизм данных

• Параллелизм задач

• Шаблон fork-join

Неструктурированный

Структурированный

Структурированный

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

5

Page 6: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++03 C++11 C++17+ Другие подходы

?

6

Page 7: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++03 C++11 C++17+ Другие подходы

нет

?

7

Page 8: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++03 C++11 C++17+ Другие подходы

нет

нет

?

8

Page 9: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++03 C++11 C++17+ Другие подходы

нет

нет

нет

9

Page 10: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

?

10

Page 11: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

?

11

Page 12: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

«Вручную»на

std::thread и т.п.

?

12

Page 13: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future ?

«Вручную»на

std::thread и т.п.

Нет

13

Page 14: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

«Вручную»на

std::thread и т.п.

?

Нет

14

Page 15: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

«Вручную»на

std::thread и т.п.

task_block,Parallel STL

Нет ?

15

Page 16: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

?

«Вручную»на

std::thread и т.п.

task_block,Parallel STL

Нет Parallel STL (par_vec)

16

Page 17: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

MPI*, Microsoft AAL*Intel TBB flow graph,Qualcomm MARE* и

другие

«Вручную»на

std::thread и т.п.

task_block,Parallel STL ?

Нет Parallel STL (par_vec)

17

Page 18: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

MPI*, Microsoft AAL*Intel TBB flow graph,Qualcomm MARE* и

другие

«Вручную»на

std::thread и т.п.

task_block,Parallel STL

OpenMP*, Intel TBB, Cilk*, Nvidia Thrust

Microsoft PPL*, Qualcomm MARE* и

другие

Нет Parallel STL (par_vec) ?

18

Page 19: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Поддержка параллелизма в С++

С++11 С++17+ Другие подходы

std::async, std::future

resumableфункции,

развитие std::asyncи std::future

MPI*, Microsoft AAL*Intel TBB flow graph,Qualcomm MARE* и

другие

«Вручную»на

std::thread и т.п.

task_block,Parallel STL

OpenMP*, Intel TBB, Cilk*, Nvidia Thrust

Microsoft PPL*, Qualcomm MARE* и

другие

Нет Parallel STL (par_vec)

intrinsics, auto-vectrorization, Intel® Cilk™ Plus, OpenCL*,

Nvidia CUDA*, OpenMP* 4, Open ACC

и другие

19

Page 20: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

20

Page 21: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

0

flag

1

flag

0

flag

21

Page 22: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flag

1

flag

0

flag

22

Page 23: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flagT2

1

flag

0

flag

23

Page 24: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flagT2

1

flag

1

flag

24

Page 25: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flagT2

1

flag

1

flag

25

Page 26: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flagT2

1

flag

0

flag

26

Page 27: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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;

}

Сработает на двух потоках?

T10

flagT2

1

flag

0

flag

27

Page 28: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Гонки данных

Пример: i++;

Поток №1 Поток №2Общийсчётчик

0

Чтение 0

Сложение 0

Запись 1

Чтение 1

Сложение 1

Запись 2

Поток №1 Поток №2Общийсчётчик

0

Чтение 0

Чтение 0

Сложение 0

Сложение 0

Запись 1

Запись 1

28

Page 29: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Чем гонки данных так неприятны?

Программы, в которых есть гонки данных, проявляютнедетерминированность в своём исполнении:

• Иногда дают верный результат

• Иногда дают ошибочный результат

Такие программы обычно работают корректно намаленьком количестве потоков с небольшим наборомданных.

Проблемы проявляются чаще, когда количествопотоков и время выполнения программы возрастает.

Отладка таких программ затруднительна!

29

Page 30: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Критические секции

• Это участки кода, которые выполняются потоками эксклюзивно.

• Реализованы при помощи примитивов синхронизации:

• pthread_mutex (Linux*)

• CRITICAL_SECTION (Windows*)

Критические секции устраняют гонки данных!

Критические секции исполняются последовательно!

Нужно понять, что должно исполняться эксклюзивно!

30

Page 31: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Взаимная блокировка

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

Пример: дорожные пробки.Машины не могут повернуть или развернуться.

31

Page 32: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Взаимная блокировка (пример)

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

32

Page 33: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Активная взаимная блокировка

http://stackoverflow.com/a/27997039/2882509

33

Page 34: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Ложное разделение ресурсовнеумышленное разделение данных в кэш-линии

Условия:

Два или более потока «работают» с одной и той же кэш-линией, но с разными адресами в памяти.

Хотя бы один поток пишет в свой адрес памяти, фактически помечая кэш-линию на других ядрах как устаревшую.

Последствия:

При следующем обращении по своему адресу ядру будет необходимо обратиться к памяти снова, чтобы загрузить «свежие» данные из неё.

34

Page 35: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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

Ложное разделение ресурсов (пример)

Пусть NUM_PROCS = 2:

35

Page 36: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

void* work(int tid) {

for (int j = 0; j < ITERATIONS; j++) {

for (int i = ;

i < ; i++)

{

a[i] = i + a[i] * b[i];

}

}

}

Ложное разделение ресурсов (исправленный вариант)

int chunks = N / NUM_PROCS;

tid * chunks

(tid + 1) * chunks

float sum = 0.0f;

localSum[tid] = sum;

sum += a[i];

36

Page 37: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Библиотека для параллельного программирования на C++:

Упрощает написание параллельных алгоритмов и скрывает явное управление потоками;

Автоматически адаптируется к системе и позволяет достигнуть максимальной масштабируемости приложения;

Кроссплатформенная: Windows *, Linux *, Mac OS* и другие

http://threadingbuildingblocks.org/

Intel® Threading Building Blocks(Intel® TBB)

37

Page 38: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Настольные компьютеры

Планшеты

Смарфоны

Ноутбуки

Нетбуки

Встроенное ПО

Кластеры

Рабочие станции

Серверы

Облако/Датацентры Сопроцессоры

Ниша Intel® TBB

MPI

OpenMP

Intel® TBB

38

Page 39: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Структура Intel® TBB

Параллельные алгоритмы и структуры данных

Потоки и синхронизация Управление памятью и задачами

Параллельные алгоритмы

Эффективная реализация

типовых шаблонов параллелизма

Конкурентные контейнеры

Контейнеры в стиле STL с возможностью конкурентного доступа без внешних

блокировок

Планировщик задач

Обеспечивает параллелизм на уровне задач, балансировка методом перехвата

работы

Потоки

Обёртки для

системных вызовов

Другое

Потокобезопасныетаймеры и

поддержка С++ исключений

Масштабируемый менеджер памяти

Спроектирован для параллельных программ

Примитивы синхронизации

Атомарные операции и различного рода мьютексы

Вычислительныйграф (Flow Graph)

Набор классов для описания

вычислительных графов, которые

могут исполняться параллельно

Локальнаяпамять потока

Неограниченное число локальных

переменных потока (TLS)

39

Page 40: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Шаблоны параллельных алгоритмов

Page 41: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Шаблоны параллельных алгоритмов

41

Page 42: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Fork-join запускает исполнение нескольких задач одновременно и затем дожидается завершения каждой из них• Удобен в применении для

функциональной и рекурсивной декомпозиции• Используется как базовый

блок для построения других шаблонов

Примеры: Сортировка слиянием, быстрая сортировка (Хоара), другие алгоритмы «разделяй-и-властвуй»

Шаблон: Fork-Join

42

Page 43: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Функциональная декомпозиция

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

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

Локальные переменные функций

43

Page 44: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Fork-Join в Intel® TBB

task_group g;

...

g.run( functor1 );

...

g.run( functor2 );

...

g.wait();

Для небольшого предопределённого количества задач

parallel_invoke( functor1, functor2, ...);

Когда количество задач велико или заранее неизвестно

44

Page 45: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример: быстрая сортировка

template<typename I>

void fork_join_qsort(I begin, I end) {

typedef typename

std::iterator_traits<I>::value_type T;

if (begin != end) {

const I pivot = end - 1;

const I middle = std::partition(begin, pivot,

std::bind(std::less<T>(), _1, *pivot));

std::swap(*pivot, *middle);

tbb::parallel_invoke(

fork_join_qsort(begin, middle),

fork_join_qsort(middle + 1, end)

);

}

}

45

Page 46: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Рекурсивный (вложенный) параллелизм

46

Page 47: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Эффективная рекурсия с fork-join

• Легко «вкладывается»

• Накладные расходы делятся между потоками

• Именно так устроены tbb::parallel_for, tbb::parallel_reduce

Рекурсивный fork-join обеспечивает высокую степень параллелизма

47

Page 48: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Map применяет указанную функцию к каждому элементу из заданного набора• Это может быть некий

набор данных или абстрактный индекс

• В серийной программе это частный случай итерирования –независимые операции.

A = map(f)(B);

Примеры: цветовая коррекция изображений; преобразование координат; трассировка лучей; методы Монте-Карло

Шаблон: Map

48

Page 49: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Параллелизм по данным

Последовательный код

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

49

Page 50: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Параллелизм по данным

Разделяемая

память

Поток №0 Поток №2

Поток №1

f ( )

f ( )

f ( )

50

Page 51: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

tbb::parallel_for

parallel_for( lower, upper, functor );

Применить functor(i) ко всем i [lower, upper)

Предоставляется в нескольких вариантах

parallel_for( lower, upper, stride, functor );

Применить functor(i), изменяя i с заданным шагом

parallel_for( range, functor );

Применить functor(subrange) для набора subrange из range

51

Page 52: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример с parallel_for

void saxpy( float a, float x[], float (&y)[], size_t n ) {

tbb::parallel_for( size_t(0), n, [&]( size_t i ) {

y[i] += a * x[i];

});

}

void saxpy( float a, float x[], float (&y)[], size_t n ) {

size_t gs = std::max( n / 1000, 1000 );

tbb::parallel_for( tbb::blocked_range<size_t>(0,n,gs),

[&]( tbb::blocked_range<size_t> r ) {

for( size_t i = r.begin(); i != r.end(); ++i )

y[i] += a * x[i];

}, tbb::simple_partitioner() );

}

52

Page 53: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Управление распределением работы

parallel_for( range, functor, simple_partitioner() );

affinity_partitioner affp;

parallel_for( range, functor, affp );

parallel_for( range, functor, auto_partitioner() );

Рекурсивное деление на максимально возможную глубину

Глубина деления подбирается динамически

Деление запоминается и по возможности воспроизводится

53

Page 54: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Ещё пример: параллелизм в 2D

tbb::parallel_for(

tbb::blocked_range2d<int>(0,m,0,n),

[&](tbb::blocked_range2d<int> r ) {

int i, j;

for(i=r.rows().begin(); i!=r.rows().end(); ++i)

for(j=r.cols().begin(); j!=r.cols().end(); ++j )

a[i][j] = f(b[i][j]);

});

// serial

for( int i=0; i<m; ++i )

for( int j=0; j<n; ++j )

a[i][j] = f(b[i][j]);

Декомпозиция «плиткой» /*tiling*/ в 2D может приводить к лучшей локальности данных, чем вложенные параллельные циклы в 1D.

54

Page 55: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Если parallel_for не подходит

parallel_for_each( first, last, functor );

Применить functor(*iter) ко всем элементам контейнера

•Параллельная версия std::for_each

•Работает со стандартными контейнерами

parallel_do( first, last, functor );

То же с возможностью добавить работу «на лету»

[]( work_item, parallel_do_feeder& feeder ) {

<обработка полученного work_item>

if( <в процессе создан new_work_item> )

feeder.add( new_work_item );

};

Добавление данных для обработки:

55

Page 56: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Reduce объединяет, при помощи ассоциативной операции, все элементы набора в один элемент

• Например, reduce можно использовать, чтобы найти сумму элементов или максимальный элемент

b = reduce(f)(B);

Примеры: вычисление агрегатных функций; операции с матрицами; численное интегрирование

Шаблон: Reduce /* свёртка */

56

Page 57: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Reduce в Intel® TBB

enumerable_thread_specific<T> sum;

parallel_for( 0, n, [&]( int i ) {

sum.local() += a[i];

});

T total = sum.combine(std::plus<T>());

T sum = parallel_reduce(

blocked_range<int>(0,n),

0.f,

[&](blocked_range<int> r, T s) -> T {

for( int i=r.begin(); i!=r.end(); ++i )

s += a[i];

return s;

},

std::plus<T>()

);

При помощи класса enumerable_thread_specific

При помощи функции parallel_reduce

57

Page 58: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Способ с enumerable_thread_specific

Подходит, если:

Операция коммутативна

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

enumerable_thread_specific<T> sum;

...

parallel_for( 0, n, [&]( int i ) {

sum.local() += a[i];

});

T total = sum.combine(std::plus<T>());

Обращение к локальной копии

Применяет указанную операцию для свёртки

локальных копий

Контейнер для thread-local

представлений

58

Page 59: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Способ с parallel_reduce

Подходит, если

Операция некоммутативна, но ассоциативна

Использование диапазона улучшает производительность

string concat = parallel_reduce(

blocked_range<int>(0, n),

string(),

[&](blocked_range<int> r, string s)->string

{

for( int i=r.begin(); i!=r.end(); ++i )

s += a[i];

return s;

},

std::plus<string>()

);

Свёртка частичных результатов

Нейтральный элемент

Свёртка поддиапазона

Начальное значение для свёртки

59

Page 60: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример: поиск наименьшего элемента// Find index of smallest element in a[0...n-1]

int ParallelMinIndex ( const float a[], int n ) {

struct MyMin {float value; int idx;};

const MyMin identity = {FLT_MAX,-1};

MyMin result = tbb::parallel_reduce(

tbb::blocked_range<int>(0,n),

identity,

[&] (tbb::blocked_range<int> r, MyMin current) -> MyMin {

for( int i=r.begin(); i<r.end(); ++i )

if( a[i] < current.value ) {

current.value = a[i];

current.idx = i;

}

return current;

},

[] (const MyMin a, const MyMin b) {

return a.value<b.value? a : b;

});

return result.idx;

}

60

Page 61: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Комментарии к parallel_reduce

Можно указывать необязательный аргумент partitioner

Аналогично parallel_for

Для неассоциативных операций рекомендуется parallel_deterministic_reduce

Воспроизводимый результат для арифметики с плавающей точкой

Но не соответствует результату в серийном коде

Рекомендуется явно указывать гранулярность

Не позволяет задать partitioner

61

Page 62: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Scan полезен в сценариях, когда данные по сути зависимы.

• Для достижения параллелизма необходимо слегка «извернуться».

• Необходимо, чтобы операция удовлетворяла правилу ассоциативности.

Примеры: вычисление частичных сумм, сортировка подсчётом, ранжирование списка, интегральные изображения

Шаблон: Scan /* частичные суммы */

62

Page 63: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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

63

Page 64: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Параллелизм в шаблоне scantemplate <class T> class Body {

T sum;

T* const y;

const T* const z;

public:

Body(T* y_,const T* z_):sum(0),z(z_),y(y_){}

T get_sum() const {return sum;}

template<typename Tag>

void operator()(

const blocked_range<int>& r,Tag) {

T temp = sum;

for(int i=r.begin();i<r.end();++i) {

temp = temp+z[i];

if(Tag::is_final_scan())

y[i] = temp;

}

sum = temp;

}

Body(Body& b,split):z(b.z),y(b.y),sum(0){}

void reverse_join(Body& a){sum = a.sum+sum;}

void assign(Body& b) {sum = b.sum;}

};

float DoParallelScan(T y[],const T z[],int n){

Body body(y,z);

parallel_scan(blocked_range<int>(0,n),body);

return body.get_sum();

}

Вр

ем

я

64

Page 65: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Шаблон: Sort /* сортировка */

template<typename RandomAccessIterator>

void parallel_sort( RandomAccessIterator begin,

RandomAccessIterator end );

template<typename RandomAccessIterator, typename Compare>

void parallel_sort( RandomAccessIterator begin,

RandomAccessIterator end,

const Compare& comp );

template<typename Container>

void parallel_sort( Container c );

template<typename Container>

void parallel_sort( Container c, const Compare& comp );

65

Page 66: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Вычислительные графы вIntel® Threading Building Blocks

Page 67: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Состоит из объекта графа

• Задан набором узлов и рёбер

• Позволяет дождаться завершения всей работы внутри графа

Интерфейс Intel TBB flow graph

Объект графа

Узел графа

Ребро

67

Page 68: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пользователь задаёт узлы и рёбра, взаимодействует с графом, и дожидается его завершения

Пример «Hello World»

tbb::flow::graph g;

tbb::flow::continue_node< tbb::flow::continue_msg >

h( g, []( const continue_msg & ) { std::cout << “Hello “; } );

tbb::flow::make_edge( h, w );

tbb::flow::continue_node< tbb::flow::continue_msg >

w( g, []( const continue_msg & ) { std::cout << “World\n“; } );

h.try_put(continue_msg());

g.wait_for_all();

f() f()

h w

68

Page 69: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Типы узлов

Функциональныеузлы

f() f() f(x) f(x)

source_node continue_node function_node multifunction_node

Буферизирующиеузлы

buffer_node queue_node priority_queue_node sequencer_node

1 023

Разделяющие и объединяющие

узлы

queueing join reserving join tag matching join split_node indexer_node

Другие

broadcast_node write_once_node overwrite_node limiter_node

Intel TBB Flow Graph позволяет описывать как графы зависимостей, так и граф потока данных

69

Page 70: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Граф зависимостей

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

Виды вычислительных графов

f()

continue_node

f()

f()

f(x)

f(x)

f(x)

function_node

Граф потока данных

Описывает не только зависимости между вычислительными узлами, но соединяющие рёбра служат каналами передачи данных

70

Page 71: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример с нелинейными зависимостямиstruct body {

std::string my_name;

body( const char *name ) : my_name(name) {}

void operator()( continue_msg ) const {

printf("%s\n", my_name.c_str());

}

};

int main() {

graph g;

broadcast_node< continue_msg > start(g);

continue_node< continue_msg > a( g, body("A") );

continue_node< continue_msg > b( g, body("B") );

continue_node< continue_msg > c( g, body("C") );

continue_node< continue_msg > d( g, body("D") );

continue_node< continue_msg > e( g, body("E") );

make_edge( start, a ); make_edge( start, b );

make_edge( a, c ); make_edge( b, c );

make_edge( c, d ); make_edge( a, e );

for (int i = 0; i < 3; ++i ) {

start.try_put( continue_msg() );

g.wait_for_all();

}

return 0;

}

A B

E C

D

A B

E C

D

71

Page 72: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

struct cube {

int operator()(int v) {

return v * v * v;

}

};

class sum {

int &my_sum;

public:

sum( int &s ) : my_sum(s) {}

int operator()( tuple<int, int> v ) {

my_sum += get<0>(v) + get<1>(v);

return my_sum;

}

};

struct square {

int operator()(int v)

{

return v * v;

}

};

72

Page 73: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данныхint main() {

int result = 0;

graph g;

broadcast_node<int> input(g);

function_node<int, int> squarer( g, unlimited, square() );

function_node<int, int> cuber( g, unlimited, cube() );

join_node< tuple<int, int>, queueing > j( g );

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

make_edge( input, squarer );

make_edge( input, cuber );

make_edge( squarer, input_port<0>(j) );

make_edge( cuber, input_port<1>(j) );

make_edge( j, summer );

for (int i = 1; i <= 3; ++i)

input.try_put(i);

g.wait_for_all();

printf("Final result is %d\n", result);

return 0;

}

73

Page 74: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer1

broadcast_node<int> input(g);

input.try_put(1);

Максимальный параллелизм = 1

74

Page 75: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 3

1

2

broadcast_node<int> input(g);

input.try_put(2);

75

Page 76: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 5

1

function_node<int, int> squarer( g, unlimited, square() );

function_node<int, int> cuber( g, unlimited, cube() );

2

2

76

Page 77: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 5

1

broadcast_node<int> input(g);

input.try_put(3);

2

2

3

77

Page 78: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 4

1

join_node< tuple<int, int>, queueing > j( g );

4

2

3

78

Page 79: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 6

1

function_node<int, int> squarer( g, unlimited, square() );

function_node<int, int> cuber( g, unlimited, cube() );

4

2

3

3

79

Page 80: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Максимальный параллелизм = 5

1

join_node< tuple<int, int>, queueing > j( g );

4

2

3

3

80

Page 81: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

1

Результат = 0Максимальный параллелизм = 6

4

int result = 0;

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

1

2

3

3

81

Page 82: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

Результат = 0Максимальный параллелизм = 4

4

join_node< tuple<int, int>, queueing > j( g );

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

1

3

3

1

8

82

Page 83: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

Результат = 0Максимальный параллелизм = 2

4

join_node< tuple<int, int>, queueing > j( g );

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

1

1

89

27

83

Page 84: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

Результат = 5Максимальный параллелизм = 2

1

join_node< tuple<int, int>, queueing > j( g );

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

8

9

27

84

Page 85: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

f(x)

f(x)

f(x)squarer

cuber

summer

Результат = 14Максимальный параллелизм = 2

9

join_node< tuple<int, int>, queueing > j( g );

function_node< tuple<int, int>, int >

summer( g, serial, sum(result) );

27

85

Page 86: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Пример графа, обрабатывающего поток данных

Результат = 50Максимальный параллелизм = 1

g.wait_for_all();

printf("Final result is %d\n", result);

f(x)

f(x)

f(x)squarer

cuber

summer

86

Page 87: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Разложение Холецкого (𝐴 = 𝐿𝐿𝑇)

(a) flow based implementation

(b) dependence based implementation

Aparna Chandramowlishwaran, Kathleen Knobe, and Richard Vuduc, “Performance Evaluation of Concurrent Collections on High-Performance Multicore Computing Systems”, 2010 Symposium on Parallel & Distributed Processing (IPDPS), April 2010.

87

Page 88: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Инструмент с графическим интерфейсом, позволяющий:

Создавать вычислительные узлы и задавать зависимости между ними

Генерировать исходный код на C++

Flow Graph Designer

Позволяет запускать приложения, основанные на Intel TBB flow graph, чтобы:

Собрать информацию времени выполнения

Отобразить топологию графа

Получить информацию о проблемах производительности

Экспериментальная версия доступна на whatif.intel.com

88

Page 89: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Вместо явного указания асинхронности в коде, программист описывает структуру алгоритма; Intel TBB автоматически использует возможности для параллельного исполнения узлов в графе

Планировщик Intel TBB даёт:

автоматическое распределение и динамическую балансировку работы

сочетаемость с другими параллельными конструкциями Intel TBB, например, вложенный параллельный цикл внутри вычислительного узла

Граф сохраняет состояние между запусками и позволяет многократное исполнение

Ограничение Intel TBB flow graph

Не рекомендуется использовать блокирующий API (например, для работы с сетью или диском) внутри узлов графа. В графе может быть использован специальный узел async_node для взаимодействия с внешними активностями

Преимущества Intel TBB flow graph

89

Page 90: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Планировщик задач вIntel® Threading Building Blocks

Page 91: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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

• Вновь созданные задача кладётся в начало очереди.

• Поток обрабатывает задачи, забирая их из начала очереди.

• Если у потока нет работы:

• Выбирается случайный поток-жертва

• Делается попытка забрать задачу из конца очереди потока-жертвы

91

Page 92: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

Каждый процессор имеет свою рабочую очередь.

P P P P

порождение

Порождениезадачи!

92

Page 93: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

P P P P

порождениеПорождение

задачи!Порождение

задачи!

порождение

порождение

Порождениезадачи!

Порождение добавляет задачу в очередь.Это горячий путь! Должен быть быстрым!

93

Page 94: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

P

следующая

P P P

следующая

порождение

Возврат иззадачи!

Возврат иззадачи!

Возврат иззадачи!

Когда задача завершена, из очереди вынимается следующая.

94

Page 95: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

P

следующая

P P P

Возврат иззадачи!

95

Page 96: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

P P

перехват

P P

Перехват!

Когда у процессора нет работы, он перехватывает её у другого процессора.Это “холодный путь”, может стоить дороже.

96

Page 97: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Перехват работы в планировщике задач

P P P P

Порождениезадачи!

При достаточном параллелизме, перехваты работы редки, и мы получаем линейное ускорение (без учёта эффектов памяти)

порождение

97

Page 98: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Преимущества двухсторонней очереди

Общие операции дёшевы.Накладные расходы на редких операциях.

Доступ к началу очереди есть только у её потока-владельца.

Нет необходимости в дорогих атомарных операциях.

Локальная работа потока находится в начале очереди.

Она была только что порождена скорей всего ещё в кэше.

Нелокальная работа находится в конце очереди.

Порождена раньше всех, скорей всего, из кэша уже вытеснена.

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

98

Page 99: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Рекурсивный параллелизм

[Data, Data+N)

[Data, Data+N/2)[Data+N/2, Data+N)

[Data, Data+N/k)

[Data, Data+GrainSize)

Доступные для перехвата задачи

99

Page 100: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Рекурсивный параллелизм

[Data, Data+N)

[Data, Data+N/2)[Data+N/2, Data+N)

[Data, Data+N/k)

[Data, Data+GrainSize) Поток сначала исполняет

задачи «в глубину», такимобразом, пользуясь локальностью данных.

100

Page 101: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Рекурсивный параллелизм

[Data, Data+N)

[Data, Data+N/2)[Data+N/2, Data+N)

[Data, Data+N/k)

[Data, Data+GrainSize)

Другие рабочие потоки первоначально перехватывают работу «в ширину», забирая старые, бОльшие куски задачи.

Поток сначала исполняет задачи «в глубину», таким образом, пользуясь локальностью данных.

101

Page 102: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Рекурсивный параллелизм

[Data, Data+N)

[Data, Data+N/2)[Data+N/2, Data+N)

[Data, Data+N/k)

[Data, Data+GrainSize)

102

Page 103: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Библиотека для параллельного программирования на C++:

Упрощает написание параллельных алгоритмов и скрывает явное управление потоками;

Автоматически адаптируется к системе и позволяет достигнуть максимальной масштабируемости приложения;

Кроссплатформенная: Windows *, Linux *, Mac OS* и другие

http://threadingbuildingblocks.org/

Intel® Threading Building Blocks(Intel® TBB)

103

Page 104: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на
Page 105: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Backup

105

Page 106: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

• Конвейер – цепочка из стадий обработки потока данных

• Некоторые стадии могут иметь состояние

• Можно обрабатывать данные по мере поступления: “online”

Примеры: сжатие/распаковка данных, обработка сигналов, фильтрация изображений

Шаблон: Pipeline /* конвейер */

106

Page 107: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Конвейер

Разные данные на разных стадиях

Разные данные в одной стадии, если там нет состояния

Данные на выходе могут быть переупорядочены

Может понадобиться буферизация между стадиями

107

Page 108: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

parallel_pipeline (

ntoken,

make_filter<void,T>(

filter::serial_in_order,

[&]( flow_control & fc ) -> T{

T item = f();

if( !item ) fc.stop();

return item;

}

) &

make_filter<T,U>(

filter::parallel, g

) &

make_filter<U,void>(

filter:: serial_in_order, h

)

);

f

g

h

Использование конвейера

108

Page 109: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Стадии конвейера

Серийная стадия может поддерживать состояние

make_filter<X,Y>(

filter::serial_in_order,

[&]( X x ) -> Y {

extern int count;

++count;

Y y = bar(x);

return y;

}

)

Параллельная стадия –функциональное преобразование

make_filter<X,Y>(

filter::parallel,

[]( X x ) -> Y {

Y y = foo(x);

return y;

}

)

Преобразование X в Y

Отсутствие «гонок» –ответственность программиста

Данные поступают в порядке, заданном на предыдущей упорядоченной стадии

109

Page 110: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

make_filter<X,void>(

filter::serial_in_order,

[&]( X x ) {

cout << x;

}

)

Стадии конвейера: вход и выход

make_filter<void,Y>(

filter::serial_in_order,

[&]( flow_control& fc ) -> Y {

Y y;

cin >> y;

if( cin.fail() ) fc.stop();

return y;

}

)

Тип “из” - void

Стадии могут быть любого

типа

Первая стадия получает

специальный аргумент

Результат передаётся дальше по конвейеру, но

игнорируется после flow_control::stop()

Тип “в” - void

110

Page 111: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Построение конвейера

make_filter<X,Y>(

...

)

&

make_filter<Y,Z>(

...

)

• Стадии соединяются при помощи operator&

Тип данных должен совпадать

X

Y

Z

Алгебра типов

make_filter<T,U>(mode,functor) filter_t<T,U>

filter_t<T,U> & filter_t<U,V> filter_t<T,V>

111

Page 112: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

Запуск конвейера

parallel_pipeline( size_t ntoken,

const filter_t<void,void>& filter );

Ограничение на кол-во данных в

обработке

Цепочка стадий voidvoid.

• Один поток проводит данные через множество этапов

• Предпочтение обработке имеющихся элементов

Эффективное использование

кэша

• Функциональная декомпозиция не масштабируется

• Параллельные стадии улучшают ситуацию

• Производительность ограничена серийными стадиями

Масштаби-руемость

112

Page 113: Обзор библиотеки Intel® Threading uilding locks · Уровни параллелизма (аппаратное обеспечение) •Параллелизм на

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

113