SlideShare a Scribd company logo
1 of 56
Download to read offline
1
2 
Асинхронность и 
сопрограммы: 
обработка данных 
Григорий Демченко 
cтарший разработчик
3 
План Обзор технологий Предлагаемый поход Вопросы Обсуждение Дальнейшие улучшения Выводы
4 
Обзор технологий
5 
Map Возможна параллельная обработка с помощью контейнера для хранения результатов Не требуется синхронизация для обработки, только ожидание завершения стадий Каждая стадия ждет завершения предыдущей Проблемы: 
–Агрегация 
–Фильтрация 
–Работает хорошо только 1 к 1 
Парсинг 
Преобразование 
Обработка
6 
Reduce 
Агрегация Подсчет количества определенных слов Подсчет статистики по определенным метрикам Суть: уменьшение количества данных, «сжатие» для определенных целей 
#1 
Reduce 
#2 
#3
7 
Проблемы традиционных подходов Требуется синхронизация Сложный контроль потребления памяти Последовательное выполнение стадий Нагрузка на планировщик Внешние взаимодействия: 
–сетевые запросы 
–обращение к базе данных 
–обращение к диску
8 
Предлагаемый подход
9 
Что хочется? Эффективно использовать сеть: получение и посылка данных Эффективно использовать процессор: запускать задачи, не дожидаясь завершения стадий Эффективно использовать память: выделять память под конкретные нужды Разгрузка планировщика: планировать более крупные задачи Нацеленность на результат: получение первых конечных данных как можно быстрее По возможности не использовать синхронизацию явно Максимизация параллельности операций Обработка сложных сценариев (например, петли)
10 
Задача Выдать 20 наиболее используемых слов сайта
11 
Обработка данных Преобразование одних данных в другие Data Oriented Design – всё есть преобразование данных 
Преобразование 
Исходные данные 
Результат
12 
Диаграмма преобразования данных 
Фильтр 
Парсинг: URL 
Загрузка 
Парсинг: текст 
Парсинг: 
href 
Разделение слов 
host 
path 
host 
body 
url 
body 
paragraph 
word 
url
13 
Диаграмма преобразования данных 
Фильтр 
Парсинг: URL 
Загрузка 
Парсинг: 
текст 
Парсинг: href 
Разделение слов 
host 
path 
host body 
url 
body 
paragraph 
Async DNS resolving 
Async partial reading 
Header parsing 
word 
url
14 
Диаграмма преобразования данных 
Фильтр 
Парсинг: URL 
Загрузка 
Парсинг: 
текст 
Парсинг: href 
Разделение слов 
host 
path 
host body 
url 
body 
paragraph 
Async DNS resolving 
Async partial reading 
Header parsing 
word 
url 
url
15 
Как реализовать? Обратные связи – традиционные способы не подходят Асинхронность в обработчиках
16 
Канал 
Парсинг: текст 
Разделение слов 
paragraph 
Канал: 
Channel<std::string>
17 
Канал: параллельность 
Парсинг: 
текст 
Разделение слов 
paragraph 
Канал: 
Channel<std::string> 
Парсинг: 
текст 
Парсинг: 
текст 
Разделение слов
18 
Канал: интерфейс put – посылка значения get – извлечение значения Потокобезопасный Можно: for (auto&& w: wordsChan) { ... } 
template<typename T> 
struct Channel 
{ 
bool empty() const; 
void put(T val); 
bool get(T& val); 
T get(); 
void open(); 
void close(); 
};
19 
Канал: параллельность 
Парсинг: 
текст 
Разделение слов 
paragraph 
Канал: Channel<std::string> 
Парсинг: 
текст 
Парсинг: 
текст 
Разделение слов 
Channel::put 
Channel::get
20 
Канал: параллельность 
Парсинг: 
текст 
Разделение слов 
paragraph 
Канал: 
Channel<std::string> 
Парсинг: 
текст 
Парсинг: 
текст 
Разделение слов 
Channel::put 
Channel::get 
Channel::close 
returns: false
21 
Сложности Канал может быть пустым, что делать потребителю? Как обрабатывать асинхронные взаимодействия? Сколько использовать обработчиков для параллельной работы?
22 
Решение: сопрограммы! Подпрограмма: выполняются все действия перед возвратом управления Сопрограмма: частичное выполнение действий перед возвратом управления Сопрограмма обобщает понятие подпрограммы, т.е. подпрограмма - это частный случай сопрограммы. Для эффективной реализации на С++ будем использовать boost.context.
23 
Сопрограмма 
Сопрограмма 
Планировщик 
async: socket.read() 
yield 
read completed 
Channel: get() 
… 
Channel empty: get() 
… 
Channel::put 
… 
resume 
yield 
resume
24 
Обработчики Связь двух каналов 
template<typename T_src, typename T_dst, typename F_pipe> 
void piping(T_src& s, T_dst& d, F_pipe f, int n = 1) 
{ 
goN(n, [&s, &d, f] { 
auto c = closer(d); 
f(s, d); 
}); 
} 
piping(c1, c2, [](Channel<int>& src, Channel<int>& dst) { 
for (int v: src) 
dst.put(v + 1); 
}); 
closer: автоматически закрывает канал 
goN: асинхронно запускает n сопрограмм
25 
Обработчики Связь двух каналов 1 к 1 (map) 
template<typename T_src, typename T_dst, typename F_pipe> 
void piping1to1(T_src& s, T_dst& d, F_pipe f, int n = 1) 
{ 
piping(s, d, [f] (T_src& s, T_dst& d) { 
for (auto&& v: s) 
d.put(std::move(f(v))); 
}, n); 
} 
piping1to1(c1, c2, [](int v) { 
return v + 1; 
}, 10); 
будет запущено 10 обработчиков
26 
Разделение каналов 
go([&] { 
auto c1 = closer(contentHref); 
auto c2 = closer(contentText); 
for (auto&& c: content) 
{ 
contentHref.put(c); 
contentText.put(c.second); 
} 
}); 
Split 
Парсинг: текст 
Парсинг: 
href 
host + body 
body 
host + body 
body
27 
Пример обработчика: загрузка 
StrPair loadContent(const StrPair& url) 
{ 
auto&& host = url.first; 
auto&& path = url.second; 
Resolver r; 
Resolver::EndPoints ends = r.resolve(host, 80); 
VERIFY(ends != Resolver::EndPoints(), "Cannot resolve hostname: " + host); 
Socket s; 
s.connect(*ends); 
// ... 
} 
Загрузка 
host + body 
host + path 
асинхронный 
асинхронный
28 
Пример обработчика: ссылки Преобразование ссылки из строки в host+path 
StrPair parseUrl(const Str& url) 
{ 
static const regex e("http://([wd._-]*[wd_-]+)(.*)", regex::icase); 
smatch what; 
bool result = regex_search(url, what, e); 
if (!result) 
return {}; 
Str host = what[1]; 
Str path = what[2]; 
if (path.empty()) 
path = "/"; 
return {host, path}; 
} 
piping1to01(filteredUrl, parsedUrl, parseUrl); 
piping1to01: игнорирует пустые элементы
29 
Пример обработчика: слова Разделение текста на отдельные слова 
void splitWords(const Str& text, Channel<Str>& words) 
{ 
static const regex e("([a-zA-Z]+)"); 
sregex_token_iterator i = make_regex_token_iterator(text, e, 1); 
sregex_token_iterator ie; 
while (i != ie) 
words.put(*i++); 
} 
piping1toMany(text, words, splitWords); 
piping1toMany: один ко многим
30 
Петля Помещаем url после разбора снова в фильтр: piping1toMany(contentHref, url, parseHref); Как оборвать петлю? 
Фильтр 
Парсинг: URL 
Загрузка 
Парсинг: 
href 
host 
path 
host 
body 
url 
url
31 
Обработка петель Решение: использовать closeAndWait 
int threads = std::thread::hardware_concurrency(); 
ThreadPool tp(threads, "tp"); 
Channel<Str> url; 
url.put("http://www.boost.org"); 
closeAndWait(tp, url); 
template<typename T_channel> 
void closeAndWait(ThreadPool& tp, T_channel& c) 
{ 
tp.wait(); 
c.close(); 
tp.wait(); 
} 
засыпание обработчиков на Channel::get 
закрываем самый первый канал 
выход из всех обработчиков
32 
Результат Результат для 1000 страниц http://www.boost.org 
Слово 
Количество 
the 
10988 
of 
4943 
to 
4838 
and 
4837 
a 
4421 
boost 
3193 
for 
3136 
is 
3103 
in 
2637 
library 
1951 
that 
1755 
be 
1622 
as 
1358 
are 
1310 
with 
1301 
c 
1260 
it 
1170 
or 
1157 
this 
1095 
can 
1094
33 
Вопросы
34 
Количество обработчиков Какое число обработчиков необходимо в случае: 
–Лёгких задач? 
–Тяжелых задач? 
–Сетевых операций?
35 
Количество обработчиков Какое число обработчиков необходимо в случае: 
–Лёгких задач ~1-2 
–Тяжелых задач = числу ядер 
–Сетевых операций >> числа ядер
36 
Обработка блокирующих вызовов Каким образом обрабатывать блокирующие вызовы в случае: 
–Обращения к диску? 
–Синхронные запросы к удаленной БД?
37 
Обработка блокирующих вызовов Каким образом обрабатывать блокирующие вызовы в случае: 
–Обращения к диску 
–Синхронные запросы к удаленной БД 
Ответ: запускать в отдельном пуле потоков, число потоков >> числа ядер
38 
Кеширование DNS запросов 
Загрузка 
host + body 
host + path
39 
Кеширование DNS запросов 
struct DNSCache 
{ 
void add(const Str& host); 
Resolver::Endpoints get(const Str& host) const; 
private: 
static Resolver::Endpoints resolve(const Str& host); 
mutable std::mutex mutex; 
std::unordered_map<Str, Resolver::Endpoints> cache; 
}; 
Загрузка 
host + body 
host + path
40 
Кеширование DNS запросов 
struct DNSCache 
{ 
void add(const Str& host); 
Resolver::Endpoints get(const Str& host) const; 
private: 
static Resolver::Endpoints resolve(const Str& host); 
mutable std::mutex mutex; 
std::unordered_map<Str, Resolver::Endpoints> cache; 
}; 
Загрузка 
host + body 
host + path
41 
Кеширование DNS запросов 
Загрузка 
host + body 
host + path 
Resolver 
host + endpoint 
состояние: 
host → endpoint
42 
Нагрузка на планировщик 
Какова нагрузка на планировщик в случае частого обмена сообщениями через каналы? 
bool get(T& val) { 
Lock lock(mutex); 
if (!queue.empty()) { 
val = std::move(queue.front()); 
queue.pop(); 
return true; 
} 
if (closed) 
return false; 
Waiter w(val); 
waiters.push(w); 
lock.release(); 
deferProceed([this, &w](Handler proceed) { 
w.setProceed(std::move(proceed)); 
mutex.unlock(); 
}); 
return w.hasValue(); 
} 
значение в очереди => сразу возвращаем 
создаем ожидающего и добавляем его в список 
устанавливаем обработчик для возобновления выполнения 
после продолжения значение записывается в переменную val (при наличии)
43 
Нагрузка на планировщик 
Планировщик используется только при вызове proceed()! 
Combining – техника; нет нагрузки в случае простаивания 
void put(T val) 
{ 
Lock lock(mutex); 
Waiter* w = waiters.pop(); 
if (w) 
{ 
lock.unlock(); 
w->proceed(std::move(val)); 
} 
else 
{ 
queue.emplace(std::move(val)); 
} 
} 
если есть ожидающий => передаем значение непосредственно ему и возобновляем выполнение 
добавляем значение в очередь 
аналогично реализуются: 
•неблокирующие мьютексы 
•неблокирующие condition variables
44 
Обсуждение
45 
Петли Легко реализуются Нет проблем с завершением
46 
Каналы: ограничение по размеру Реализация: 2 очереди для ожидания вместо одной Ограничивает потребление памяти Сетевое использование: TCP flow control Контролирует latency
47 
Обработчики и состояние Отдавайте предпочтение обработчикам без состояний, т.к. они позволяют параллельное выполнение стадии Reduce-стадии как правило имеют состояние Часто можно разбить reduce-стадии на несколько независимых, результат объединить на следующей стадии
48 
Дальнейшие улучшения
49 
Буферизированные каналы Позволяют снизить lock contention на каналы Увеличивают throughput Увеличивают latency
50 
Планировщик «в глубину» Обычно используют планировщик «в ширину», т.е. очередь задач. Вместо очереди задач можно использовать стек задач. Получаем планировщик «в глубину» с другими свойствами.
51 
Планировщик «в глубину» 
Преимущества: Более быстрое получение первых результатов Снижение нагрузки на обработчики за счет более равномерного распределения данных между стадиями Уменьшение потребления памяти «Прогретые» процессорные кеши Отлично работает в связке с bounded каналами, заставляя данные более активно перемещаться к результату 
Недостатки: Отсутствие fairness Потеря контроля над latency
52 
Планы на будущее Распределенность Отказоустойчивость Оптимизация планировщика
53 
Выводы
54 
Предлагаемый подход позволяет Реализовать простые сценарии (фильтрация, кеширование, парсинг, преобразование и т.д.) Реализовать сложные сценарии (петли, split, merge) Использовать асинхронное сетевое взаимодействие Забыть про синхронизацию Простая параллелизация: 
–Стадии выполняются параллельно, в отличие от MR 
–Несколько обработчиков одной стадии также выполняются параллельно
55 
Спасибо за внимание!
56 
http://habrahabr.ru/users/gridem 
https://github.com/gridem/Synca 
gridem@yandex-team.ru 
https://bitbucket.org/gridem/synca

More Related Content

What's hot

ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
Python&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython Meetup
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
Haskell
HaskellHaskell
HaskellDevDay
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Alexander Granin
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...Alexey Paznikov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Mikhail Matrosov
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonovComputer Science Club
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Mikhail Kurnosov
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 

What's hot (19)

ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
Python&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.byPython&Printer / Андрей Пучко / penta.by
Python&Printer / Андрей Пучко / penta.by
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Haskell
HaskellHaskell
Haskell
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)Семинар 3. Многопоточное программирование на OpenMP (часть 3)
Семинар 3. Многопоточное программирование на OpenMP (часть 3)
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 

Viewers also liked

Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsPlatonov Sergey
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ ProgrammerPlatonov Sergey
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверPlatonov Sergey
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыPlatonov Sergey
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеSergey Platonov
 
C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...Gianluca Padovani
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtSergey Platonov
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17Sergey Platonov
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 

Viewers also liked (13)

Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Promises, Promises
Promises, PromisesPromises, Promises
Promises, Promises
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 

Similar to Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“

Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеYandex
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...Mikhail Kurnosov
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1Michael Karpov
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x IntroductionFedor Vompe
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...Alexey Paznikov
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)Ontico
 
Олесь Писаренко "Открываем Яндекс.Танк"
Олесь Писаренко "Открываем Яндекс.Танк"Олесь Писаренко "Открываем Яндекс.Танк"
Олесь Писаренко "Открываем Яндекс.Танк"Yandex
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...Alexey Paznikov
 
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыТехнологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыPositive Development User Group
 
Ekb 2013 artemkin(1)
Ekb 2013 artemkin(1)Ekb 2013 artemkin(1)
Ekb 2013 artemkin(1)Optima-PROMO
 
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графах
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графахПавел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графах
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графахYandex
 

Similar to Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“ (20)

Web лекция 1
Web   лекция 1Web   лекция 1
Web лекция 1
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программирование
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...
Лекция 6: Многопоточное программирование: часть 2 (Speedup, Amdahl's law, POS...
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x Introduction
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
 
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
SDN & DEVOPS ?= ❤: Практики использования SDN / Александр Шалимов (ЦПИКС, МГУ)
 
Олесь Писаренко "Открываем Яндекс.Танк"
Олесь Писаренко "Открываем Яндекс.Танк"Олесь Писаренко "Открываем Яндекс.Танк"
Олесь Писаренко "Открываем Яндекс.Танк"
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
 
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструментыТехнологии анализа бинарного кода приложений: требования, проблемы, инструменты
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
 
Ekb 2013 artemkin(1)
Ekb 2013 artemkin(1)Ekb 2013 artemkin(1)
Ekb 2013 artemkin(1)
 
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графах
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графахПавел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графах
Павел Артёмкин — Разработка C++ API для реализации алгоритмов на больших графах
 
JavaDay'14
JavaDay'14JavaDay'14
JavaDay'14
 

More from Platonov Sergey

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3Platonov Sergey
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Platonov Sergey
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеPlatonov Sergey
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxPlatonov Sergey
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIPlatonov Sergey
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IPlatonov Sergey
 
QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практикеPlatonov Sergey
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутовPlatonov Sergey
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Platonov Sergey
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Platonov Sergey
 
HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийPlatonov Sergey
 
Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08Platonov Sergey
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Platonov Sergey
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьPlatonov Sergey
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыPlatonov Sergey
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузераPlatonov Sergey
 

More from Platonov Sergey (20)

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практике
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутов
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
 
HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
 
Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 

Григорий Демченко, “Асинхронность и сопрограммы: обработка данных“

  • 1. 1
  • 2. 2 Асинхронность и сопрограммы: обработка данных Григорий Демченко cтарший разработчик
  • 3. 3 План Обзор технологий Предлагаемый поход Вопросы Обсуждение Дальнейшие улучшения Выводы
  • 5. 5 Map Возможна параллельная обработка с помощью контейнера для хранения результатов Не требуется синхронизация для обработки, только ожидание завершения стадий Каждая стадия ждет завершения предыдущей Проблемы: –Агрегация –Фильтрация –Работает хорошо только 1 к 1 Парсинг Преобразование Обработка
  • 6. 6 Reduce Агрегация Подсчет количества определенных слов Подсчет статистики по определенным метрикам Суть: уменьшение количества данных, «сжатие» для определенных целей #1 Reduce #2 #3
  • 7. 7 Проблемы традиционных подходов Требуется синхронизация Сложный контроль потребления памяти Последовательное выполнение стадий Нагрузка на планировщик Внешние взаимодействия: –сетевые запросы –обращение к базе данных –обращение к диску
  • 9. 9 Что хочется? Эффективно использовать сеть: получение и посылка данных Эффективно использовать процессор: запускать задачи, не дожидаясь завершения стадий Эффективно использовать память: выделять память под конкретные нужды Разгрузка планировщика: планировать более крупные задачи Нацеленность на результат: получение первых конечных данных как можно быстрее По возможности не использовать синхронизацию явно Максимизация параллельности операций Обработка сложных сценариев (например, петли)
  • 10. 10 Задача Выдать 20 наиболее используемых слов сайта
  • 11. 11 Обработка данных Преобразование одних данных в другие Data Oriented Design – всё есть преобразование данных Преобразование Исходные данные Результат
  • 12. 12 Диаграмма преобразования данных Фильтр Парсинг: URL Загрузка Парсинг: текст Парсинг: href Разделение слов host path host body url body paragraph word url
  • 13. 13 Диаграмма преобразования данных Фильтр Парсинг: URL Загрузка Парсинг: текст Парсинг: href Разделение слов host path host body url body paragraph Async DNS resolving Async partial reading Header parsing word url
  • 14. 14 Диаграмма преобразования данных Фильтр Парсинг: URL Загрузка Парсинг: текст Парсинг: href Разделение слов host path host body url body paragraph Async DNS resolving Async partial reading Header parsing word url url
  • 15. 15 Как реализовать? Обратные связи – традиционные способы не подходят Асинхронность в обработчиках
  • 16. 16 Канал Парсинг: текст Разделение слов paragraph Канал: Channel<std::string>
  • 17. 17 Канал: параллельность Парсинг: текст Разделение слов paragraph Канал: Channel<std::string> Парсинг: текст Парсинг: текст Разделение слов
  • 18. 18 Канал: интерфейс put – посылка значения get – извлечение значения Потокобезопасный Можно: for (auto&& w: wordsChan) { ... } template<typename T> struct Channel { bool empty() const; void put(T val); bool get(T& val); T get(); void open(); void close(); };
  • 19. 19 Канал: параллельность Парсинг: текст Разделение слов paragraph Канал: Channel<std::string> Парсинг: текст Парсинг: текст Разделение слов Channel::put Channel::get
  • 20. 20 Канал: параллельность Парсинг: текст Разделение слов paragraph Канал: Channel<std::string> Парсинг: текст Парсинг: текст Разделение слов Channel::put Channel::get Channel::close returns: false
  • 21. 21 Сложности Канал может быть пустым, что делать потребителю? Как обрабатывать асинхронные взаимодействия? Сколько использовать обработчиков для параллельной работы?
  • 22. 22 Решение: сопрограммы! Подпрограмма: выполняются все действия перед возвратом управления Сопрограмма: частичное выполнение действий перед возвратом управления Сопрограмма обобщает понятие подпрограммы, т.е. подпрограмма - это частный случай сопрограммы. Для эффективной реализации на С++ будем использовать boost.context.
  • 23. 23 Сопрограмма Сопрограмма Планировщик async: socket.read() yield read completed Channel: get() … Channel empty: get() … Channel::put … resume yield resume
  • 24. 24 Обработчики Связь двух каналов template<typename T_src, typename T_dst, typename F_pipe> void piping(T_src& s, T_dst& d, F_pipe f, int n = 1) { goN(n, [&s, &d, f] { auto c = closer(d); f(s, d); }); } piping(c1, c2, [](Channel<int>& src, Channel<int>& dst) { for (int v: src) dst.put(v + 1); }); closer: автоматически закрывает канал goN: асинхронно запускает n сопрограмм
  • 25. 25 Обработчики Связь двух каналов 1 к 1 (map) template<typename T_src, typename T_dst, typename F_pipe> void piping1to1(T_src& s, T_dst& d, F_pipe f, int n = 1) { piping(s, d, [f] (T_src& s, T_dst& d) { for (auto&& v: s) d.put(std::move(f(v))); }, n); } piping1to1(c1, c2, [](int v) { return v + 1; }, 10); будет запущено 10 обработчиков
  • 26. 26 Разделение каналов go([&] { auto c1 = closer(contentHref); auto c2 = closer(contentText); for (auto&& c: content) { contentHref.put(c); contentText.put(c.second); } }); Split Парсинг: текст Парсинг: href host + body body host + body body
  • 27. 27 Пример обработчика: загрузка StrPair loadContent(const StrPair& url) { auto&& host = url.first; auto&& path = url.second; Resolver r; Resolver::EndPoints ends = r.resolve(host, 80); VERIFY(ends != Resolver::EndPoints(), "Cannot resolve hostname: " + host); Socket s; s.connect(*ends); // ... } Загрузка host + body host + path асинхронный асинхронный
  • 28. 28 Пример обработчика: ссылки Преобразование ссылки из строки в host+path StrPair parseUrl(const Str& url) { static const regex e("http://([wd._-]*[wd_-]+)(.*)", regex::icase); smatch what; bool result = regex_search(url, what, e); if (!result) return {}; Str host = what[1]; Str path = what[2]; if (path.empty()) path = "/"; return {host, path}; } piping1to01(filteredUrl, parsedUrl, parseUrl); piping1to01: игнорирует пустые элементы
  • 29. 29 Пример обработчика: слова Разделение текста на отдельные слова void splitWords(const Str& text, Channel<Str>& words) { static const regex e("([a-zA-Z]+)"); sregex_token_iterator i = make_regex_token_iterator(text, e, 1); sregex_token_iterator ie; while (i != ie) words.put(*i++); } piping1toMany(text, words, splitWords); piping1toMany: один ко многим
  • 30. 30 Петля Помещаем url после разбора снова в фильтр: piping1toMany(contentHref, url, parseHref); Как оборвать петлю? Фильтр Парсинг: URL Загрузка Парсинг: href host path host body url url
  • 31. 31 Обработка петель Решение: использовать closeAndWait int threads = std::thread::hardware_concurrency(); ThreadPool tp(threads, "tp"); Channel<Str> url; url.put("http://www.boost.org"); closeAndWait(tp, url); template<typename T_channel> void closeAndWait(ThreadPool& tp, T_channel& c) { tp.wait(); c.close(); tp.wait(); } засыпание обработчиков на Channel::get закрываем самый первый канал выход из всех обработчиков
  • 32. 32 Результат Результат для 1000 страниц http://www.boost.org Слово Количество the 10988 of 4943 to 4838 and 4837 a 4421 boost 3193 for 3136 is 3103 in 2637 library 1951 that 1755 be 1622 as 1358 are 1310 with 1301 c 1260 it 1170 or 1157 this 1095 can 1094
  • 34. 34 Количество обработчиков Какое число обработчиков необходимо в случае: –Лёгких задач? –Тяжелых задач? –Сетевых операций?
  • 35. 35 Количество обработчиков Какое число обработчиков необходимо в случае: –Лёгких задач ~1-2 –Тяжелых задач = числу ядер –Сетевых операций >> числа ядер
  • 36. 36 Обработка блокирующих вызовов Каким образом обрабатывать блокирующие вызовы в случае: –Обращения к диску? –Синхронные запросы к удаленной БД?
  • 37. 37 Обработка блокирующих вызовов Каким образом обрабатывать блокирующие вызовы в случае: –Обращения к диску –Синхронные запросы к удаленной БД Ответ: запускать в отдельном пуле потоков, число потоков >> числа ядер
  • 38. 38 Кеширование DNS запросов Загрузка host + body host + path
  • 39. 39 Кеширование DNS запросов struct DNSCache { void add(const Str& host); Resolver::Endpoints get(const Str& host) const; private: static Resolver::Endpoints resolve(const Str& host); mutable std::mutex mutex; std::unordered_map<Str, Resolver::Endpoints> cache; }; Загрузка host + body host + path
  • 40. 40 Кеширование DNS запросов struct DNSCache { void add(const Str& host); Resolver::Endpoints get(const Str& host) const; private: static Resolver::Endpoints resolve(const Str& host); mutable std::mutex mutex; std::unordered_map<Str, Resolver::Endpoints> cache; }; Загрузка host + body host + path
  • 41. 41 Кеширование DNS запросов Загрузка host + body host + path Resolver host + endpoint состояние: host → endpoint
  • 42. 42 Нагрузка на планировщик Какова нагрузка на планировщик в случае частого обмена сообщениями через каналы? bool get(T& val) { Lock lock(mutex); if (!queue.empty()) { val = std::move(queue.front()); queue.pop(); return true; } if (closed) return false; Waiter w(val); waiters.push(w); lock.release(); deferProceed([this, &w](Handler proceed) { w.setProceed(std::move(proceed)); mutex.unlock(); }); return w.hasValue(); } значение в очереди => сразу возвращаем создаем ожидающего и добавляем его в список устанавливаем обработчик для возобновления выполнения после продолжения значение записывается в переменную val (при наличии)
  • 43. 43 Нагрузка на планировщик Планировщик используется только при вызове proceed()! Combining – техника; нет нагрузки в случае простаивания void put(T val) { Lock lock(mutex); Waiter* w = waiters.pop(); if (w) { lock.unlock(); w->proceed(std::move(val)); } else { queue.emplace(std::move(val)); } } если есть ожидающий => передаем значение непосредственно ему и возобновляем выполнение добавляем значение в очередь аналогично реализуются: •неблокирующие мьютексы •неблокирующие condition variables
  • 45. 45 Петли Легко реализуются Нет проблем с завершением
  • 46. 46 Каналы: ограничение по размеру Реализация: 2 очереди для ожидания вместо одной Ограничивает потребление памяти Сетевое использование: TCP flow control Контролирует latency
  • 47. 47 Обработчики и состояние Отдавайте предпочтение обработчикам без состояний, т.к. они позволяют параллельное выполнение стадии Reduce-стадии как правило имеют состояние Часто можно разбить reduce-стадии на несколько независимых, результат объединить на следующей стадии
  • 49. 49 Буферизированные каналы Позволяют снизить lock contention на каналы Увеличивают throughput Увеличивают latency
  • 50. 50 Планировщик «в глубину» Обычно используют планировщик «в ширину», т.е. очередь задач. Вместо очереди задач можно использовать стек задач. Получаем планировщик «в глубину» с другими свойствами.
  • 51. 51 Планировщик «в глубину» Преимущества: Более быстрое получение первых результатов Снижение нагрузки на обработчики за счет более равномерного распределения данных между стадиями Уменьшение потребления памяти «Прогретые» процессорные кеши Отлично работает в связке с bounded каналами, заставляя данные более активно перемещаться к результату Недостатки: Отсутствие fairness Потеря контроля над latency
  • 52. 52 Планы на будущее Распределенность Отказоустойчивость Оптимизация планировщика
  • 54. 54 Предлагаемый подход позволяет Реализовать простые сценарии (фильтрация, кеширование, парсинг, преобразование и т.д.) Реализовать сложные сценарии (петли, split, merge) Использовать асинхронное сетевое взаимодействие Забыть про синхронизацию Простая параллелизация: –Стадии выполняются параллельно, в отличие от MR –Несколько обработчиков одной стадии также выполняются параллельно
  • 55. 55 Спасибо за внимание!
  • 56. 56 http://habrahabr.ru/users/gridem https://github.com/gridem/Synca gridem@yandex-team.ru https://bitbucket.org/gridem/synca