SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Downloaden Sie, um offline zu lesen
ПАРАЛЛЕЛИЗМ В C++:
УПРАВЛЯЙТЕ ПРИЛОЖЕНИЕМ,
А НЕ ПОТОКАМИ!
C++ User Group Meeting
Алексей Куканов, Intel Corporation
Нижний Новгород, 2014
Параллелизм – норма жизни
• Мультиядерные и
многоядерные
процессоры
• SIMD, SIMT, SMT
• Степень аппаратного |||
продолжает расти
• Требуется явный ||| на
уровне софта
• Здесь и далее:
||| означает параллелизм
С++ до 2011: ||| на свой страх и риск
Стандарт языка С++ (1998)
• Строго последовательная модель, ||| не рассматривается вовсе
Разнообразные библиотеки потоков /*threads*/
• POSIX threads, WinAPI threads, Boost, …
• Чаще всего, кросс-платформенные обёртки над средствами ОС
OpenMP
• Языковое расширение на основе прагм, развиваемое
консорциумом производителей
• Ориентировано на HPC (Fortran,C); слабо интегрировано с С++
«Молодая шпана»
• TBB (Intel), PPL (Microsoft), GCD (Apple), CUDA (NVidia),
Cilk++ (CilkArts => Intel), академические разработки, ...
• Потоки, если и используются, скрыты от программиста
С++11 и |||: необходимые основы
• Усовершенствованная модель памяти
• Многопоточная модель исполнения программы
• «Гонки данных» /*data races*/ объявлены UB
• Переменные, локальные для потока: thread_local
• Поддержка в библиотеке:
• Потоки исполнения: std::thread
• Атомарные переменные: std::atomic<>
• Синхронизация: std::mutex и др., std::condition_variable
• Асинхронное исполнение: std::future, std::async
Базовые блоки для многопоточных программ
Как это всё использовать?
• Управление потоками исполнения
• Распределение работы между
потоками
• Синхронизацию при использовании
разделяемых данных
Необходимо
разработать
• Накладные расходы
• Балансировку нагрузки
• Масштабируемость
• Компонуемость составных частей
программы
Необходимо
учесть
Общепринятое мнение:
Параллельные программы – это сложно
Многопоточность – это сложно
Будьте экспертом в своей области!
«Кто виноват?»
Слишком низкий уровень
абстракции
Отсутствие необходимых
знаний и опыта
«Что делать?»
Нанять эксперта в разработке
многопоточных программ
Стать таким экспертом
Использовать другие подходы
к параллелизму
Некоторые концепции
действительно сложны!




Deja vu
Мы это всё уже проходили, и не раз
• В 1990-х: «оконный» интерфейс для DOS, класс string и т.д.
• До появления STL: списки, очереди, ... и использующие их
алгоритмы
Не надо «изобретать велосипед»!
• Используйте C++-библиотеки «параллельных шаблонов»
/*parallel patterns*/
• Есть выбор: от Intel, Microsoft, NVidia, AMD, Qualcomm, …
• Многие с открытым исходным кодом
Сделай сам
Готовые
библиотеки
Стандарт
Параллелизм без потоков – это как?
• Определите ||| на алгоритмическом уровне
• Разбейте алгоритм на отдельные вычислительные блоки
• Определите зависимости между блоками
• Найдите подходящий параллельный шаблон
• Примените этот шаблон с помощью выбранной
библиотеки
• Если нужного шаблона не нашлось, но есть API для
использования «задач», попробуйте применить его
• Оставьте библиотеке сложную и рутинную работу
• Профит!
6 March
Параллельное программирование
может быть доступным
Параллельные шаблоны
Intel® Cilk™ Plus
• Минимальное расширение C и C++
• Семантика последовательной программы
Три новых
ключевых слова
• Что исполнять параллельно - а не как
• Балансировка методом перехвата работы
||| в виде задач
• Глобальные переменные для ||| программ
• Отсутствие гонок и блокировок
Гиперобъекты
• Векторные операции с массивами
Расширенная
индексная нотация
• Параллельное применение функции ко
всем элементам массива
Элементные
функции
• Подсказка векторизующему компиляторуДиректива SIMD
Intel® Threading Building Blocks
• Портируемое решение
• Основана на С++ шаблонах /*templates*/
Библиотека С++
• Что исполнять параллельно - а не как
• Балансировка методом перехвата работы
||| в виде задач
• Типовые шаблоны параллелизма
• Эффективная реализация
Параллельные
алгоритмы
• Контейнеры в стиле STL
• Не требуют внешних блокировок
Конкурентные
контейнеры
• Мьютексы с разными свойствами
• Атомарные операции
Примитивы
синхронизации
• Спроектирован для параллельных
программ
Масштабируемый
менеджер памяти
• Fork-join запускает
исполнение нескольких
задач одновременно и
затем дожидается
завершения каждой из них
• Удобен в применении для
функциональной и
рекурсивной декомпозиции
• Используется как базовый
блок для построения
других шаблонов
Примеры: Сортировка слиянием,
быстрая сортировка (Хоара), другие
алгоритмы «разделяй-и-властвуй»
Шаблон: Fork-Join
Использование
parallel_invoke( a, b, c );
task_group g;
g.run( a );
g.run( b );
g.run_and_wait( c );
Intel® TBB
cilk_spawn a();
cilk_spawn b();
c();
cilk_sync();
Intel® Cilk™ Plus
Fork-Join в Intel® Cilk™ Plus
• spawn – асинхронный вызов функции
x = cilk_spawn f(*p++);
y = g(*p--);
cilk_sync;
z = x+y;
Необязательное
присваивание
Аргументы вычисляются до
асинхронного вызова
x=f(tmp);
tmp=*p++;
y = g(*p--);
z = x+y;
Подробнее о cilk_sync
• Область действия cilk_sync – вся вызывающая функция
• В конце функции есть неявный cilk_sync
void bar() {
for( int i=0; i<3; ++i ) {
cilk_spawn f(i);
if( i&1 ) cilk_sync;
}
// implicit cilk_sync
}
Неявный
cilk_sync
f(0);
i=0;
++i;
f(1);
f(2);
++i;
Fork-Join в Intel® TBB
task_group g;
...
g.run( functor1 );
...
g.run( functor2 );
...
g.wait();
Для небольшого предопределённого кол-ва задач
parallel_invoke( functor1, functor2, ...);
Когда кол-во задач велико или заранее неизвестно
Пример: быстрая сортировка
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::bind2nd(std::less<T>(), *pivot));
std::swap(*pivot, *middle);
tbb::parallel_invoke(
fork_join_qsort(begin, middle),
fork_join_qsort(middle + 1, end)
);
}
}
Рекурсивный (вложенный) параллелизм
19
Эффективная рекурсия с fork-join
• Легко «вкладывается»
• Накладные расходы
делятся между
потоками
• Именно так устроены
cilk_for,
tbb::parallel_for,
tbb::parallel_reduce
Рекурсивный fork-join обеспечивает
высокую степень параллелизма
• Map применяет
указанную функцию к
каждому элементу из
заданного набора
• Это может быть некий
набор данных или
абстрактный индекс
• В серийной программе
это частный случай
итерирования –
независимые операции.
A = map(f)(B);
Примеры: цветовая коррекция
изображений; преобразование
координат; трассировка лучей;
методы Монте-Карло
Шаблон: Map
Использование
parallel_for( 0, n, [&]( int i ) {
a[i] = f(b[i]);
});
parallel_for(
blocked_range<int>(0,n),
[&](blocked_range<int> r ) {
for( int i=r.begin();
i!=r.end(); ++i )
a[i] = f(b[i]);
});
Intel® TBB
cilk_for (int i=0; i<n; ++i)
a[i] = f(b[i]);
#pragma simd
for( int i=0; i<n; ++i )
a[i] = f(b[i]);
Intel® Cilk™ Plus
Пример с #pragma simd
• Указание на параллелизм по данным
• В стиле прагм OpenMP
• Позволяет указывать параметры /*clauses*/ для
«продвинутых» случаев использования
• С минимальными изменениями добавлена в спецификацию
OpenMP 4.0
• Компилятор может применить векторные инструкции
• Игнорируется, если не распознаётся компилятором
void saxpy( float a, float x[], float y[], size_t n )
{
#pragma simd
for( size_t i=0; i<n; ++i )
y[i] += a*x[i];
}
cilk_for
• Параллельное исполнение итераций цикла
• Ограничение: необходимо просчитать итерационное
пространство до начала исполнения цикла
cilk_for( type index = expr; condition; incr )
body;
Только интегральные
типы и итераторы
произвольного доступа
Отсутствие «гонок» между итерациями -
на совести программиста
index relop limit
limit relop index
!= < >
>= <=
index += stride
index -= stride
index++
++index
index--
--index
Выражения limit и stride
вычисляются один раз
Пример с cilk_for
void saxpy( float a, float x[], float y[], size_t n )
{
cilk_for( size_t i=0; i<n; ++i )
y[i] += a*x[i];
}
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
Пример с 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, 1 );
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 )
a[i] = f(b[i]);
}, tbb::simple_partitioner() );
}
Управление распределением работы
parallel_for( range, functor, simple_partitioner() );
affinity_partitioner affp;
parallel_for( range, functor, affp );
parallel_for( range, functor, auto_partitioner() );
Рекурсивное деление на максимально возможную глубину
Глубина деления подбирается динамически
Деление запоминается и по возможности воспроизводится
Ещё пример: ||| в 2D
29
tbb::parallel_for(
tbb::blocked_range2d<int>(0,m,0,n),
[&](tbb::blocked_range2d<int> r ) {
for( int i=r.rows().begin(); i!=r.rows().end(); ++i )
for( int j=r.rows().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.
Если 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 );
};
• Reduce объединяет, при
помощи ассоциативной
операции, все элементы
набора в один элемент
• Например, reduce можно
использовать, чтобы
найти сумму элементов
или максимальный эл-т
b = reduce(f)(B);
Примеры: вычисление агрегатных
функций; операции с матрицами;
численное интегрирование
Шаблон: Reduce /*свёртка*/
Использование
enumerable_thread_specific<float> sum;
parallel_for( 0, n, [&]( int i ) {
sum.local() += a[i];
});
... = sum.combine(std::plus<float>());
Intel® TBB
cilk::reducer_opadd<float> sum = 0;
cilk_for( int i=0; i<n; ++i )
sum += a[i];
... = sum.get_value();
#pragma simd reduction(+:sum)
float sum=0;
for( int i=0; i<n; ++i )
sum += a[i];
Intel® Cilk™ Plus
sum = parallel_reduce(
blocked_range<int>(0,n),
0.f,
[&](blocked_range<int> r,
float s) -> float
{
for( int i=r.begin();
i!=r.end(); ++i )
s += a[i];
return s;
},
std::plus<float>()
);
Пример: свёртка с #pragma simd
• Параметр reduction указывает переменную и
операцию для свёртки
float dot( float x[], float y[], size_t n ) {
float sum = 0;
#pragma simd reduction(+:sum)
for( size_t i=0; i<n; ++i )
sum += x[i]*y[i];
return sum;
}
Свёртка операцией +
в переменную sum
Редукторы /*Reducers*/ в Cilk Plus
• Глобальные переменные для свёртки
• Не требуют блокировки при использовании
• Поддержка любых ассоциативных операций
• Можно определить свой редуктор
cilk::reducer_opadd<float> sum = 0;
...
cilk_for( size_t i=1; i<n; ++i )
sum += f(i);
... = sum.get_value();
Переменная не связана
с конкретным циклом
Обновляется
локальное
представление
Получение
глобального
представления
Более подробно о редукторах
cilk::reducer_opadd<float> sum;
void f( int m ) {
sum += m;
}
float g() {
cilk_spawn f(1);
f(2);
cilk_sync;
return sum.get_value();
}
Глобальная переменная
sum1 += 1
sum1 += 2
sum1 += 1
sum2 += 2
sum2 = 0
sum1 += sum2
Новое
представ-
ление!
Свёртка двух
представлений
Пример с enumerable_thread_specific
• Подходит, если:
• Операция коммутативна
• Дорого вычислять свёртку (напр. большой размер операндов)
enumerable_thread_specific<BigMatrix> sum;
...
parallel_for( 0, n, [&]( int i ) {
sum.local() += a[i];
});
... = sum.combine(std::plus<BigMatrix>());
Обращение к
локальной копии
Применяет указанную
операцию для свёртки
локальных копий
Контейнер для
thread-local
представлений
Пример с parallel_reduce
• Подходит, если
• Операция некоммутативна
• Использование диапазонов /*range*/ улучшает
производительность
sum = parallel_reduce(
blocked_range<int>(0,n),
0.f,
[&](blocked_range<int> r, T s) -> float
{
for( int i=r.begin(); i!=r.end(); ++i )
s += a[i];
return s;
},
std::plus<T>()
);
Свёртка частичных
реультатов
Нейтральный элемент
Свёртка поддиапазона
Начальное значение
для свёртки
Пример: поиск наименьшего элемента
// 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;
}
Комментарии к parallel_reduce
• Можно указывать необязательный аргумент partitioner
• Аналогично parallel_for
• Для неассоциативных операций рекомендуется
parallel_deterministic_reduce
• Воспроизводимый результат для арифметики с плавающей
точкой
• Но не соответствует результату в серийном коде
• Рекомендуется явно указывать гранулярность
• Не позволяет задать partitioner
• Конвейер – цепочка из
стадий обработки
потока данных
• Некоторые стадии
могут иметь состояние
• Можно обрабатывать
данные по мере
поступления: “online”Примеры: сжатие/распаковка
данных, обработка сигналов,
фильтрация изображений
Шаблон: Pipeline /*конвейер*/
||| в конвейере
• Разные данные на
разных стадиях
• Разные данные в
одной стадии, если
там нет состояния
• Данные на выходе
могут быть
переупорядочены
• Может понадобиться
буферизация между
стадиями
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
)
);
Intel® TBB
S s;
reducer_consume sink<S,U> (
&s, h
);
...
void Stage2( T x ) {
sink.consume(g(x));
}
...
while( T x = f() )
cilk_spawn Stage2(x);
cilk_sync;
Intel® Cilk™ Plus
(частный случай)
f
g
h
Использование
Стадии конвейера
Серийная стадия
может поддерживать
состояние
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
Отсутствие «гонок» –
ответственность
программиста
Данные поступают в порядке,
заданном на предыдущей
упорядоченной стадии
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
Построение конвейера
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>
Запуск конвейера
parallel_pipeline( size_t ntoken,
const filter_t<void,void>& filter );
Ограничение на
кол-во данных в
обработке
Цепочка стадий
voidvoid.
• Один поток проводит данные через
множество этапов
• Предпочтение обработке имеющихся
элементов
Эффективное
использование
кэша
• Функциональная декомпозиция не
масштабируется
• Параллельные стадии улучшают ситуацию
• Производительность ограничена серийными
стадиями
Масштаби-
руемость
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
Параллельные шаблоны
Снижение сложности с ||| шаблонами
• Об управлении потоками исполнения
• О распределении работы
• О компонуемости параллельных частей
• О переносимости на другое «железо»
Не нужно
беспокоиться
• В синхронизации
• В контроле накладных расходов
• В балансировке нагрузки
Снижается
необходимость
Параллельные программы – это доступно
Заключение
• Эффективно использовать современные процессоры
невозможно без параллельного программирования
• Поддержка параллелизма в C++ пока лишь на
базовом уровне: потоки, синхронизация и т.п.
• Тема ||| активно развивается в C++ Standard Committee
• Для эффективной и продуктивной разработки
применяйте готовые решения
• Библиотеки параллельных шаблонов
• Эффективные языковые расширения (если приемлемо)
• Cпециализированные библиотеки с поддержкой |||
Успехов в параллельном программировании!
Источники информации
T.G.Mattson, B.A.Sanders, B.L.Massingill:
Patterns for Parallel Programming,
Addison-Wesley, 2005, ISBN 978-0-321-22811-6
M.McCool, A.D.Robinson, J.Reinders:
Structured Parallel Programming,
Morgan Kaufmann, ISBN 978-0-12-415993-8
www.parallelbook.com
Intel® Threading Building Blocks,
www.threadingbuildingblocks.org
Intel® Cilk™ Plus, www.cilkplus.org
Спасибо за внимание!

Weitere ähnliche Inhalte

Was ist angesagt?

ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
Семинар 2. Многопоточное программирование на OpenMP (часть 2)
Семинар 2. Многопоточное программирование на OpenMP (часть 2)Семинар 2. Многопоточное программирование на OpenMP (часть 2)
Семинар 2. Многопоточное программирование на OpenMP (часть 2)Mikhail Kurnosov
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияAlexey Paznikov
 
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Platonov Sergey
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...Alexey Paznikov
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Platonov Sergey
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Mikhail Kurnosov
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Mikhail Kurnosov
 
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о BoostSergey Platonov
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...Alexey Paznikov
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x IntroductionFedor Vompe
 

Was ist angesagt? (20)

ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Семинар 2. Многопоточное программирование на OpenMP (часть 2)
Семинар 2. Многопоточное программирование на OpenMP (часть 2)Семинар 2. Многопоточное программирование на OpenMP (часть 2)
Семинар 2. Многопоточное программирование на OpenMP (часть 2)
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
 
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
Игорь Кудрин, «Используем неизменяемые данные и создаем качественный код»
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
 
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
Павел Сушин «Асинхронное программирование на С++: callbacks, futures, fibers»
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
 
Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)Семинар 11. Параллельное программирование на MPI (часть 4)
Семинар 11. Параллельное программирование на MPI (часть 4)
 
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x Introduction
 

Ähnlich wie Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!

Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекPython Meetup
 
Some Elements of Functional Porgamming Languages
Some Elements of Functional Porgamming LanguagesSome Elements of Functional Porgamming Languages
Some Elements of Functional Porgamming Languages_ymn
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++Andrey Karpov
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)Alexander Gornik
 
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++Pavel Tsukanov
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеYandex
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструментыRoman Dvornov
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.Igor Shkulipa
 
Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++corehard_by
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1m2rus
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Alex Tutubalin
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Dima Dzuba
 
Machine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинMachine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинIT61
 

Ähnlich wie Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками! (20)

Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
 
About Python
About PythonAbout Python
About Python
 
Some Elements of Functional Porgamming Languages
Some Elements of Functional Porgamming LanguagesSome Elements of Functional Porgamming Languages
Some Elements of Functional Porgamming Languages
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
 
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
СИ++ УМЕР. ДА ЗДРАВСТВУЕТ СИ++
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программирование
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
Dsl for c++
Dsl for c++Dsl for c++
Dsl for c++
 
Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
 
Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12Доклад в Mail.ru 01.11.12
Доклад в Mail.ru 01.11.12
 
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
 
Machine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий ЛапинMachine learning c использованием нейронных сетей, Дмитрий Лапин
Machine learning c использованием нейронных сетей, Дмитрий Лапин
 
Team workflow
Team workflowTeam workflow
Team workflow
 

Mehr von Yandex

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksYandex
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Yandex
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаYandex
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаYandex
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Yandex
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Yandex
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Yandex
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Yandex
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Yandex
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Yandex
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Yandex
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровYandex
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Yandex
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Yandex
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Yandex
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Yandex
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Yandex
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Yandex
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Yandex
 

Mehr von Yandex (20)

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 

Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!

  • 1. ПАРАЛЛЕЛИЗМ В C++: УПРАВЛЯЙТЕ ПРИЛОЖЕНИЕМ, А НЕ ПОТОКАМИ! C++ User Group Meeting Алексей Куканов, Intel Corporation Нижний Новгород, 2014
  • 2. Параллелизм – норма жизни • Мультиядерные и многоядерные процессоры • SIMD, SIMT, SMT • Степень аппаратного ||| продолжает расти • Требуется явный ||| на уровне софта • Здесь и далее: ||| означает параллелизм
  • 3. С++ до 2011: ||| на свой страх и риск Стандарт языка С++ (1998) • Строго последовательная модель, ||| не рассматривается вовсе Разнообразные библиотеки потоков /*threads*/ • POSIX threads, WinAPI threads, Boost, … • Чаще всего, кросс-платформенные обёртки над средствами ОС OpenMP • Языковое расширение на основе прагм, развиваемое консорциумом производителей • Ориентировано на HPC (Fortran,C); слабо интегрировано с С++ «Молодая шпана» • TBB (Intel), PPL (Microsoft), GCD (Apple), CUDA (NVidia), Cilk++ (CilkArts => Intel), академические разработки, ... • Потоки, если и используются, скрыты от программиста
  • 4. С++11 и |||: необходимые основы • Усовершенствованная модель памяти • Многопоточная модель исполнения программы • «Гонки данных» /*data races*/ объявлены UB • Переменные, локальные для потока: thread_local • Поддержка в библиотеке: • Потоки исполнения: std::thread • Атомарные переменные: std::atomic<> • Синхронизация: std::mutex и др., std::condition_variable • Асинхронное исполнение: std::future, std::async Базовые блоки для многопоточных программ
  • 5. Как это всё использовать? • Управление потоками исполнения • Распределение работы между потоками • Синхронизацию при использовании разделяемых данных Необходимо разработать • Накладные расходы • Балансировку нагрузки • Масштабируемость • Компонуемость составных частей программы Необходимо учесть Общепринятое мнение: Параллельные программы – это сложно
  • 6.
  • 7. Многопоточность – это сложно Будьте экспертом в своей области! «Кто виноват?» Слишком низкий уровень абстракции Отсутствие необходимых знаний и опыта «Что делать?» Нанять эксперта в разработке многопоточных программ Стать таким экспертом Использовать другие подходы к параллелизму Некоторые концепции действительно сложны!    
  • 8. Deja vu Мы это всё уже проходили, и не раз • В 1990-х: «оконный» интерфейс для DOS, класс string и т.д. • До появления STL: списки, очереди, ... и использующие их алгоритмы Не надо «изобретать велосипед»! • Используйте C++-библиотеки «параллельных шаблонов» /*parallel patterns*/ • Есть выбор: от Intel, Microsoft, NVidia, AMD, Qualcomm, … • Многие с открытым исходным кодом Сделай сам Готовые библиотеки Стандарт
  • 9. Параллелизм без потоков – это как? • Определите ||| на алгоритмическом уровне • Разбейте алгоритм на отдельные вычислительные блоки • Определите зависимости между блоками • Найдите подходящий параллельный шаблон • Примените этот шаблон с помощью выбранной библиотеки • Если нужного шаблона не нашлось, но есть API для использования «задач», попробуйте применить его • Оставьте библиотеке сложную и рутинную работу • Профит! 6 March Параллельное программирование может быть доступным
  • 11. Intel® Cilk™ Plus • Минимальное расширение C и C++ • Семантика последовательной программы Три новых ключевых слова • Что исполнять параллельно - а не как • Балансировка методом перехвата работы ||| в виде задач • Глобальные переменные для ||| программ • Отсутствие гонок и блокировок Гиперобъекты • Векторные операции с массивами Расширенная индексная нотация • Параллельное применение функции ко всем элементам массива Элементные функции • Подсказка векторизующему компиляторуДиректива SIMD
  • 12. Intel® Threading Building Blocks • Портируемое решение • Основана на С++ шаблонах /*templates*/ Библиотека С++ • Что исполнять параллельно - а не как • Балансировка методом перехвата работы ||| в виде задач • Типовые шаблоны параллелизма • Эффективная реализация Параллельные алгоритмы • Контейнеры в стиле STL • Не требуют внешних блокировок Конкурентные контейнеры • Мьютексы с разными свойствами • Атомарные операции Примитивы синхронизации • Спроектирован для параллельных программ Масштабируемый менеджер памяти
  • 13. • Fork-join запускает исполнение нескольких задач одновременно и затем дожидается завершения каждой из них • Удобен в применении для функциональной и рекурсивной декомпозиции • Используется как базовый блок для построения других шаблонов Примеры: Сортировка слиянием, быстрая сортировка (Хоара), другие алгоритмы «разделяй-и-властвуй» Шаблон: Fork-Join
  • 14. Использование parallel_invoke( a, b, c ); task_group g; g.run( a ); g.run( b ); g.run_and_wait( c ); Intel® TBB cilk_spawn a(); cilk_spawn b(); c(); cilk_sync(); Intel® Cilk™ Plus
  • 15. Fork-Join в Intel® Cilk™ Plus • spawn – асинхронный вызов функции x = cilk_spawn f(*p++); y = g(*p--); cilk_sync; z = x+y; Необязательное присваивание Аргументы вычисляются до асинхронного вызова x=f(tmp); tmp=*p++; y = g(*p--); z = x+y;
  • 16. Подробнее о cilk_sync • Область действия cilk_sync – вся вызывающая функция • В конце функции есть неявный cilk_sync void bar() { for( int i=0; i<3; ++i ) { cilk_spawn f(i); if( i&1 ) cilk_sync; } // implicit cilk_sync } Неявный cilk_sync f(0); i=0; ++i; f(1); f(2); ++i;
  • 17. Fork-Join в Intel® TBB task_group g; ... g.run( functor1 ); ... g.run( functor2 ); ... g.wait(); Для небольшого предопределённого кол-ва задач parallel_invoke( functor1, functor2, ...); Когда кол-во задач велико или заранее неизвестно
  • 18. Пример: быстрая сортировка 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::bind2nd(std::less<T>(), *pivot)); std::swap(*pivot, *middle); tbb::parallel_invoke( fork_join_qsort(begin, middle), fork_join_qsort(middle + 1, end) ); } }
  • 20. Эффективная рекурсия с fork-join • Легко «вкладывается» • Накладные расходы делятся между потоками • Именно так устроены cilk_for, tbb::parallel_for, tbb::parallel_reduce Рекурсивный fork-join обеспечивает высокую степень параллелизма
  • 21. • Map применяет указанную функцию к каждому элементу из заданного набора • Это может быть некий набор данных или абстрактный индекс • В серийной программе это частный случай итерирования – независимые операции. A = map(f)(B); Примеры: цветовая коррекция изображений; преобразование координат; трассировка лучей; методы Монте-Карло Шаблон: Map
  • 22. Использование parallel_for( 0, n, [&]( int i ) { a[i] = f(b[i]); }); parallel_for( blocked_range<int>(0,n), [&](blocked_range<int> r ) { for( int i=r.begin(); i!=r.end(); ++i ) a[i] = f(b[i]); }); Intel® TBB cilk_for (int i=0; i<n; ++i) a[i] = f(b[i]); #pragma simd for( int i=0; i<n; ++i ) a[i] = f(b[i]); Intel® Cilk™ Plus
  • 23. Пример с #pragma simd • Указание на параллелизм по данным • В стиле прагм OpenMP • Позволяет указывать параметры /*clauses*/ для «продвинутых» случаев использования • С минимальными изменениями добавлена в спецификацию OpenMP 4.0 • Компилятор может применить векторные инструкции • Игнорируется, если не распознаётся компилятором void saxpy( float a, float x[], float y[], size_t n ) { #pragma simd for( size_t i=0; i<n; ++i ) y[i] += a*x[i]; }
  • 24. cilk_for • Параллельное исполнение итераций цикла • Ограничение: необходимо просчитать итерационное пространство до начала исполнения цикла cilk_for( type index = expr; condition; incr ) body; Только интегральные типы и итераторы произвольного доступа Отсутствие «гонок» между итерациями - на совести программиста index relop limit limit relop index != < > >= <= index += stride index -= stride index++ ++index index-- --index Выражения limit и stride вычисляются один раз
  • 25. Пример с cilk_for void saxpy( float a, float x[], float y[], size_t n ) { cilk_for( size_t i=0; i<n; ++i ) y[i] += a*x[i]; }
  • 26. 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
  • 27. Пример с 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, 1 ); 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 ) a[i] = f(b[i]); }, tbb::simple_partitioner() ); }
  • 28. Управление распределением работы parallel_for( range, functor, simple_partitioner() ); affinity_partitioner affp; parallel_for( range, functor, affp ); parallel_for( range, functor, auto_partitioner() ); Рекурсивное деление на максимально возможную глубину Глубина деления подбирается динамически Деление запоминается и по возможности воспроизводится
  • 29. Ещё пример: ||| в 2D 29 tbb::parallel_for( tbb::blocked_range2d<int>(0,m,0,n), [&](tbb::blocked_range2d<int> r ) { for( int i=r.rows().begin(); i!=r.rows().end(); ++i ) for( int j=r.rows().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.
  • 30. Если 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 ); };
  • 31. • Reduce объединяет, при помощи ассоциативной операции, все элементы набора в один элемент • Например, reduce можно использовать, чтобы найти сумму элементов или максимальный эл-т b = reduce(f)(B); Примеры: вычисление агрегатных функций; операции с матрицами; численное интегрирование Шаблон: Reduce /*свёртка*/
  • 32. Использование enumerable_thread_specific<float> sum; parallel_for( 0, n, [&]( int i ) { sum.local() += a[i]; }); ... = sum.combine(std::plus<float>()); Intel® TBB cilk::reducer_opadd<float> sum = 0; cilk_for( int i=0; i<n; ++i ) sum += a[i]; ... = sum.get_value(); #pragma simd reduction(+:sum) float sum=0; for( int i=0; i<n; ++i ) sum += a[i]; Intel® Cilk™ Plus sum = parallel_reduce( blocked_range<int>(0,n), 0.f, [&](blocked_range<int> r, float s) -> float { for( int i=r.begin(); i!=r.end(); ++i ) s += a[i]; return s; }, std::plus<float>() );
  • 33. Пример: свёртка с #pragma simd • Параметр reduction указывает переменную и операцию для свёртки float dot( float x[], float y[], size_t n ) { float sum = 0; #pragma simd reduction(+:sum) for( size_t i=0; i<n; ++i ) sum += x[i]*y[i]; return sum; } Свёртка операцией + в переменную sum
  • 34. Редукторы /*Reducers*/ в Cilk Plus • Глобальные переменные для свёртки • Не требуют блокировки при использовании • Поддержка любых ассоциативных операций • Можно определить свой редуктор cilk::reducer_opadd<float> sum = 0; ... cilk_for( size_t i=1; i<n; ++i ) sum += f(i); ... = sum.get_value(); Переменная не связана с конкретным циклом Обновляется локальное представление Получение глобального представления
  • 35. Более подробно о редукторах cilk::reducer_opadd<float> sum; void f( int m ) { sum += m; } float g() { cilk_spawn f(1); f(2); cilk_sync; return sum.get_value(); } Глобальная переменная sum1 += 1 sum1 += 2 sum1 += 1 sum2 += 2 sum2 = 0 sum1 += sum2 Новое представ- ление! Свёртка двух представлений
  • 36. Пример с enumerable_thread_specific • Подходит, если: • Операция коммутативна • Дорого вычислять свёртку (напр. большой размер операндов) enumerable_thread_specific<BigMatrix> sum; ... parallel_for( 0, n, [&]( int i ) { sum.local() += a[i]; }); ... = sum.combine(std::plus<BigMatrix>()); Обращение к локальной копии Применяет указанную операцию для свёртки локальных копий Контейнер для thread-local представлений
  • 37. Пример с parallel_reduce • Подходит, если • Операция некоммутативна • Использование диапазонов /*range*/ улучшает производительность sum = parallel_reduce( blocked_range<int>(0,n), 0.f, [&](blocked_range<int> r, T s) -> float { for( int i=r.begin(); i!=r.end(); ++i ) s += a[i]; return s; }, std::plus<T>() ); Свёртка частичных реультатов Нейтральный элемент Свёртка поддиапазона Начальное значение для свёртки
  • 38. Пример: поиск наименьшего элемента // 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; }
  • 39. Комментарии к parallel_reduce • Можно указывать необязательный аргумент partitioner • Аналогично parallel_for • Для неассоциативных операций рекомендуется parallel_deterministic_reduce • Воспроизводимый результат для арифметики с плавающей точкой • Но не соответствует результату в серийном коде • Рекомендуется явно указывать гранулярность • Не позволяет задать partitioner
  • 40. • Конвейер – цепочка из стадий обработки потока данных • Некоторые стадии могут иметь состояние • Можно обрабатывать данные по мере поступления: “online”Примеры: сжатие/распаковка данных, обработка сигналов, фильтрация изображений Шаблон: Pipeline /*конвейер*/
  • 41. ||| в конвейере • Разные данные на разных стадиях • Разные данные в одной стадии, если там нет состояния • Данные на выходе могут быть переупорядочены • Может понадобиться буферизация между стадиями
  • 42. 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 ) ); Intel® TBB S s; reducer_consume sink<S,U> ( &s, h ); ... void Stage2( T x ) { sink.consume(g(x)); } ... while( T x = f() ) cilk_spawn Stage2(x); cilk_sync; Intel® Cilk™ Plus (частный случай) f g h Использование
  • 43. Стадии конвейера Серийная стадия может поддерживать состояние 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 Отсутствие «гонок» – ответственность программиста Данные поступают в порядке, заданном на предыдущей упорядоченной стадии
  • 44. 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
  • 45. Построение конвейера 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>
  • 46. Запуск конвейера parallel_pipeline( size_t ntoken, const filter_t<void,void>& filter ); Ограничение на кол-во данных в обработке Цепочка стадий voidvoid. • Один поток проводит данные через множество этапов • Предпочтение обработке имеющихся элементов Эффективное использование кэша • Функциональная декомпозиция не масштабируется • Параллельные стадии улучшают ситуацию • Производительность ограничена серийными стадиями Масштаби- руемость
  • 47. 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
  • 49. Снижение сложности с ||| шаблонами • Об управлении потоками исполнения • О распределении работы • О компонуемости параллельных частей • О переносимости на другое «железо» Не нужно беспокоиться • В синхронизации • В контроле накладных расходов • В балансировке нагрузки Снижается необходимость Параллельные программы – это доступно
  • 50. Заключение • Эффективно использовать современные процессоры невозможно без параллельного программирования • Поддержка параллелизма в C++ пока лишь на базовом уровне: потоки, синхронизация и т.п. • Тема ||| активно развивается в C++ Standard Committee • Для эффективной и продуктивной разработки применяйте готовые решения • Библиотеки параллельных шаблонов • Эффективные языковые расширения (если приемлемо) • Cпециализированные библиотеки с поддержкой ||| Успехов в параллельном программировании!
  • 51. Источники информации T.G.Mattson, B.A.Sanders, B.L.Massingill: Patterns for Parallel Programming, Addison-Wesley, 2005, ISBN 978-0-321-22811-6 M.McCool, A.D.Robinson, J.Reinders: Structured Parallel Programming, Morgan Kaufmann, ISBN 978-0-12-415993-8 www.parallelbook.com Intel® Threading Building Blocks, www.threadingbuildingblocks.org Intel® Cilk™ Plus, www.cilkplus.org