SlideShare a Scribd company logo
1 of 26
Download to read offline
Максим Хижинский, CoreHard.by Минск, 2016
Lock-free maps изнутриLock-free maps изнутри
QueueQueue
Максим Хижинский, CoreHard.by Минск, 2016
MapMap
Максим Хижинский, CoreHard.by Минск, 2016
Lock-free ordered listLock-free ordered list
Операции:
●
insert( node )
● erase( key )
●
find( key )
template <class T>
struct node {
std::atomic<node*> next_;
T data_;
};
H T52 8
Lock-free примитивы:
● atomic load/store
●
atomic compare-and-swap (CAS)
Максим Хижинский, CoreHard.by Минск, 2016
CAS — compare-and-swapCAS — compare-and-swap
template <typename T>
bool CAS( T * pAtomic, T expected, T desired )
atomically {
if ( *pAtomic == expected ) {
*pAtomic = desired;
return true;
}
else
return false;
};
bool std::atomic<T>::compare_exchange(
T& expected, T desired );
Максим Хижинский, CoreHard.by Минск, 2016
Lock-free list: insertLock-free list: insert
H T52 8
3
H T52 8
3
3. prev->next_.CAS( next, new_node )
1. find insert position for key 3
2. new_node.next_.store( next )
H T52 8
prev next
new_node
Максим Хижинский, CoreHard.by Минск, 2016
Local varsLocal vars
H T52 8
prev
3
found
erase( Key k ) {
retry:
node * prev = Head;
do {
node * found = prev->next_.load();
if ( found->key == k ) {
node * next = found->next_.load();
if (prev->next_.CAS( found, next )) {
delete found;
return true;
}
else
goto retry;
}
prev = found;
} while ( found->key < k );
return false;
}
Проблема: локальные ссылки
next
Максим Хижинский, CoreHard.by Минск, 2016
ABA-проблемаABA-проблема
52
prev
3
found next
Thread A: erase(3) Thread B
52 3
erase(3); erase(5)
2 3
insert(4)
Heap
new node(4) alloc
delete
42
preempted...
42
prev found next
5
addr(3) == addr(4)
prev->next_.CAS( found, next ) - success!!!
2 мусор
5
Максим Хижинский, CoreHard.by Минск, 2016
Tagged pointersTagged pointers
pointer tag
prev->next_.dwCAS( found, {next.ptr, prev->next_.tag + 1} )
template <class T>
struct tagged_ptr {
T * ptr;
uintptr_t tag;
};
Требует dwCAS — не везде есть
Решает только ABA-проблему
Освободить память нельзя,
нужен free-list
[ boost.lock-free ]
H T52 8
prev
3
found next
Максим Хижинский, CoreHard.by Минск, 2016
Hazard pointersHazard pointers
H T52 8
prev
3
found
erase( Key k ) {
hp_guard hp1 = get_guard();
hp_guard hp2 = get_guard();
retry:
node * prev = Head;
do {
node * found = hp2.protect( prev->next_);
if ( found->key == k )
if (prev->next_.CAS( found, found->next_.load())) {
hp_retire( found );
return true;
}
else
goto retry;
}
hp1 = hp2;
prev = found;
} while ( found->key < k );
return false;
}
Распределяем HP (TLS)
Защищаем элемент
Отложенное удаление
Максим Хижинский, CoreHard.by Минск, 2016
Hazard PointersHazard Pointers
Объявление Hazard Pointer'а – защита локальной ссылки
class hp_guard {
void * hp;
// ...
};
T * hp_guard::protect(std::atomic<T*>& what) {
T * t;
do {
hp = t = what.load();
} while (t != what.load());
return t;
}
0
1
…
K - 1
thread-local
●
HP[K]
Другой поток может
изменить what, поэтому - цикл
Максим Хижинский, CoreHard.by Минск, 2016
Hazard PointersHazard Pointers
Удаление элемента
void hp_retire( T * what ) {
push what to current_thread.Retired array
if ( current_thread.Retired is full )
hp.Scan( current_thread );
}
// сердце hazard pointer
void hp::Scan( current_thread ) {
void * guarded[K*P] = union HP[K] for all P thread;
foreach ( p in current_thread.Retired[R] )
if ( p not in guarded[] )
delete p;
}
0
1
2
…
R - 1
Retired[R]
0
1
…
K - 1
HP[K]
thread-local
Максим Хижинский, CoreHard.by Минск, 2016
Hazard pointersHazard pointers
✔ Использует только атомарные чтение/запись
 Защищает только локальные ссылки
✔ Размер массива отложенных (готовых к
удалению) элементов ограничен сверху
 Перед работой с указателем его следует
объявить как hazard
решает ABA-проблему
Физическое удаление элементов
Максим Хижинский, CoreHard.by Минск, 2016
Epoch-based SMREpoch-based SMR
Map.find( ... );
Set.insert( ... );
Map.find( ... );
Map.erase( ... )...
Thread 1
Set.find( ... );
Map.insert( ... );
Set.find( ... );
Set.insert( ... );
Thread N
Эпоха 1
RCU.sync() - ждем, пока все потоки покинут эпоху 1
Set.find( ... );
Map.insert( ... );
Set.find( ... );
Set.insert( ... );
... Map.erase;
Map.find( ... );
Set.insert( ... );
Map.find( ... );
++Эпоха
Эпоха 2
Максим Хижинский, CoreHard.by Минск, 2016
Lock-free listLock-free list
Максим Хижинский, CoreHard.by Минск, 2016
Atomic примитивы
●
atomic load/store
● atomic CAS
Safe memory
reclamation schema
(Hazard Pointers, uRCU)+Решили:
●
Проблему удаления узлов (delete)
●
ABA-проблему
Открытая проблема: параллельный insert и erase
Lock-free list: insert/eraseLock-free list: insert/erase
A: find key 3
H T52 8
prev
3
found
B: find insert pos for key 4
iprev inext
A: erase key 3
H T52 83
prev->next_.CAS( found, next )
next
B: insert key 4
H T52 83
4
iprev->next_.CAS( inext, new_item )
local vars
Максим Хижинский, CoreHard.by Минск, 2016
Marked pointerMarked pointer
[ T.Harris, 2001 ]
Двухфазное удаление:
● Логическое удаление — помечаем элемент
●
Физическое удаление — исключаем элемент
В качестве метки используем младший бит указателя
Максим Хижинский, CoreHard.by Минск, 2016
Lock-free list: marked pointerLock-free list: marked pointer
H T52 8
prev
3
found
iprev inext
nextA: erase
B: insert
A: Logical deletion - mark item found
H T52 83
found->next_.CAS( next, next | 1 )
B: iprev->next_.CAS( inext, new_item ) - failed!!!
A: Physical deletion - unlink item found
H T52 83
prev->next_.CAS( found, next )
Максим Хижинский, CoreHard.by Минск, 2016
ИтераторыИтераторы
11 Выдача итератора наружу — фактически,
ссылки на элемент списка
но - элемент в любой момент может быть
удален
Требования и контраргументы
for (auto it = list.begin(); it != list.end(); ++it)
it->do_something();
Максим Хижинский, CoreHard.by Минск, 2016
guarded_ptrguarded_ptr
template <typename T>
struct guarded_ptr {
hp_guard hp; // защищает элемент
T * ptr; // элемент списка
guarded_ptr(std::atomic<T *>& p) {
ptr = hp.protect( p ); }
~guarded_ptr() { hp.clear(); }
T * operator ->() const { return ptr; }
explicit operator bool() const
{ return ptr != nullptr; }
};
// Пример
guarded_ptr gp = list.find( key );
if ( gp ) {
// можно безопасно обращаться к полям T через gp
}
Максим Хижинский, CoreHard.by Минск, 2016
ИтераторыИтераторы
но - список постоянно изменяется
22Обход всех элементов списка
for (auto it = list.begin(); it != list.end(); ++it)
it->do_something();
Требования и контраргументы
Максим Хижинский, CoreHard.by Минск, 2016
ИтераторыИтераторы
auto it = list.begin() it == list.end()
++it; ... ++it;
H T
inserted
removed
stable
Максим Хижинский, CoreHard.by Минск, 2016
ИтераторыИтераторы
H T
H T
deleted
мусор!
it
it
Максим Хижинский, CoreHard.by Минск, 2016
Iterable lock-free listIterable lock-free list
H T
2 4 5 8
Элементы списка хранят указатели на данные
При удалении ключа обнуляется указатель, сам элемент списка остается
H T
2 4 5 8
struct node {
std::atomic<node *> next;
std::atomic<T *> data;
};Максим Хижинский, CoreHard.by Минск, 2016
Iterable lock-free listIterable lock-free list
class iterator {
node * node;
guarded_ptr<T> data; // текущий элемент
public:
iterator& operator++() {
while ( node ) {
node = node->next.load(); // не требует защиты
if ( !node ) break;
data.ptr = data.hp.protect(node->data.load());
if ( data.ptr ) break;
}
return *this;
}
T* operator ->() { return data.ptr; }
T& operator *() { return *data.ptr; }
};
Максим Хижинский, CoreHard.by Минск, 2016
Спасибо за внимание!
https://github.com/khizmax/libcds
Максим Хижинский, CoreHard.by Минск, 2016

More Related Content

What's hot

ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...Alexey Paznikov
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...Alexey Paznikov
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsPlatonov Sergey
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Platonov Sergey
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
Haskell
HaskellHaskell
HaskellDevDay
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияAlexey Paznikov
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Alexander Granin
 

What's hot (20)

ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
C++ idioms
C++ idiomsC++ idioms
C++ idioms
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Haskell
HaskellHaskell
Haskell
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 

Similar to Конкурентные ассоциативные контейнеры

Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыPlatonov Sergey
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
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
 
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...JSFestUA
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
Почему Rust стоит вашего внимания
Почему Rust стоит вашего вниманияПочему Rust стоит вашего внимания
Почему Rust стоит вашего вниманияMichael Pankov
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Семинар 4. Многопоточное программирование на OpenMP (часть 4)
Семинар 4. Многопоточное программирование на OpenMP (часть 4)Семинар 4. Многопоточное программирование на OpenMP (часть 4)
Семинар 4. Многопоточное программирование на OpenMP (часть 4)Mikhail Kurnosov
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20DefconRussia
 
Современные подходы к SAST
Современные подходы к SASTСовременные подходы к SAST
Современные подходы к SASTVladimir Kochetkov
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Mikhail Kurnosov
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Михаил Белопухов: OpenBSD: Куда катится крипто?
Михаил Белопухов: OpenBSD: Куда катится крипто?Михаил Белопухов: OpenBSD: Куда катится крипто?
Михаил Белопухов: OpenBSD: Куда катится крипто?Yandex
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьMikhail Kurnosov
 
Когда в C# не хватает C++ . Часть 3.
Когда в C# не хватает C++. Часть 3. Когда в C# не хватает C++. Часть 3.
Когда в C# не хватает C++ . Часть 3. Mikhail Shcherbakov
 

Similar to Конкурентные ассоциативные контейнеры (20)

Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
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
 
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
Почему Rust стоит вашего внимания
Почему Rust стоит вашего вниманияПочему Rust стоит вашего внимания
Почему Rust стоит вашего внимания
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Семинар 4. Многопоточное программирование на OpenMP (часть 4)
Семинар 4. Многопоточное программирование на OpenMP (часть 4)Семинар 4. Многопоточное программирование на OpenMP (часть 4)
Семинар 4. Многопоточное программирование на OpenMP (часть 4)
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20
 
Array Work C
Array Work CArray Work C
Array Work C
 
Современные подходы к SAST
Современные подходы к SASTСовременные подходы к SAST
Современные подходы к SAST
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Михаил Белопухов: OpenBSD: Куда катится крипто?
Михаил Белопухов: OpenBSD: Куда катится крипто?Михаил Белопухов: OpenBSD: Куда катится крипто?
Михаил Белопухов: OpenBSD: Куда катится крипто?
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
Лекция 4: Стек. Очередь
Лекция 4: Стек. ОчередьЛекция 4: Стек. Очередь
Лекция 4: Стек. Очередь
 
Когда в C# не хватает C++ . Часть 3.
Когда в C# не хватает C++. Часть 3. Когда в C# не хватает C++. Часть 3.
Когда в C# не хватает C++ . Часть 3.
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019corehard_by
 
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019Как не подавиться большим старым проектом. Юрий Минаев ➠  CoreHard Autumn 2019
Как не подавиться большим старым проектом. Юрий Минаев ➠ CoreHard Autumn 2019
 

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

  • 1. Максим Хижинский, CoreHard.by Минск, 2016 Lock-free maps изнутриLock-free maps изнутри
  • 4. Lock-free ordered listLock-free ordered list Операции: ● insert( node ) ● erase( key ) ● find( key ) template <class T> struct node { std::atomic<node*> next_; T data_; }; H T52 8 Lock-free примитивы: ● atomic load/store ● atomic compare-and-swap (CAS) Максим Хижинский, CoreHard.by Минск, 2016
  • 5. CAS — compare-and-swapCAS — compare-and-swap template <typename T> bool CAS( T * pAtomic, T expected, T desired ) atomically { if ( *pAtomic == expected ) { *pAtomic = desired; return true; } else return false; }; bool std::atomic<T>::compare_exchange( T& expected, T desired ); Максим Хижинский, CoreHard.by Минск, 2016
  • 6. Lock-free list: insertLock-free list: insert H T52 8 3 H T52 8 3 3. prev->next_.CAS( next, new_node ) 1. find insert position for key 3 2. new_node.next_.store( next ) H T52 8 prev next new_node Максим Хижинский, CoreHard.by Минск, 2016
  • 7. Local varsLocal vars H T52 8 prev 3 found erase( Key k ) { retry: node * prev = Head; do { node * found = prev->next_.load(); if ( found->key == k ) { node * next = found->next_.load(); if (prev->next_.CAS( found, next )) { delete found; return true; } else goto retry; } prev = found; } while ( found->key < k ); return false; } Проблема: локальные ссылки next Максим Хижинский, CoreHard.by Минск, 2016
  • 8. ABA-проблемаABA-проблема 52 prev 3 found next Thread A: erase(3) Thread B 52 3 erase(3); erase(5) 2 3 insert(4) Heap new node(4) alloc delete 42 preempted... 42 prev found next 5 addr(3) == addr(4) prev->next_.CAS( found, next ) - success!!! 2 мусор 5 Максим Хижинский, CoreHard.by Минск, 2016
  • 9. Tagged pointersTagged pointers pointer tag prev->next_.dwCAS( found, {next.ptr, prev->next_.tag + 1} ) template <class T> struct tagged_ptr { T * ptr; uintptr_t tag; }; Требует dwCAS — не везде есть Решает только ABA-проблему Освободить память нельзя, нужен free-list [ boost.lock-free ] H T52 8 prev 3 found next Максим Хижинский, CoreHard.by Минск, 2016
  • 10. Hazard pointersHazard pointers H T52 8 prev 3 found erase( Key k ) { hp_guard hp1 = get_guard(); hp_guard hp2 = get_guard(); retry: node * prev = Head; do { node * found = hp2.protect( prev->next_); if ( found->key == k ) if (prev->next_.CAS( found, found->next_.load())) { hp_retire( found ); return true; } else goto retry; } hp1 = hp2; prev = found; } while ( found->key < k ); return false; } Распределяем HP (TLS) Защищаем элемент Отложенное удаление Максим Хижинский, CoreHard.by Минск, 2016
  • 11. Hazard PointersHazard Pointers Объявление Hazard Pointer'а – защита локальной ссылки class hp_guard { void * hp; // ... }; T * hp_guard::protect(std::atomic<T*>& what) { T * t; do { hp = t = what.load(); } while (t != what.load()); return t; } 0 1 … K - 1 thread-local ● HP[K] Другой поток может изменить what, поэтому - цикл Максим Хижинский, CoreHard.by Минск, 2016
  • 12. Hazard PointersHazard Pointers Удаление элемента void hp_retire( T * what ) { push what to current_thread.Retired array if ( current_thread.Retired is full ) hp.Scan( current_thread ); } // сердце hazard pointer void hp::Scan( current_thread ) { void * guarded[K*P] = union HP[K] for all P thread; foreach ( p in current_thread.Retired[R] ) if ( p not in guarded[] ) delete p; } 0 1 2 … R - 1 Retired[R] 0 1 … K - 1 HP[K] thread-local Максим Хижинский, CoreHard.by Минск, 2016
  • 13. Hazard pointersHazard pointers ✔ Использует только атомарные чтение/запись  Защищает только локальные ссылки ✔ Размер массива отложенных (готовых к удалению) элементов ограничен сверху  Перед работой с указателем его следует объявить как hazard решает ABA-проблему Физическое удаление элементов Максим Хижинский, CoreHard.by Минск, 2016
  • 14. Epoch-based SMREpoch-based SMR Map.find( ... ); Set.insert( ... ); Map.find( ... ); Map.erase( ... )... Thread 1 Set.find( ... ); Map.insert( ... ); Set.find( ... ); Set.insert( ... ); Thread N Эпоха 1 RCU.sync() - ждем, пока все потоки покинут эпоху 1 Set.find( ... ); Map.insert( ... ); Set.find( ... ); Set.insert( ... ); ... Map.erase; Map.find( ... ); Set.insert( ... ); Map.find( ... ); ++Эпоха Эпоха 2 Максим Хижинский, CoreHard.by Минск, 2016
  • 15. Lock-free listLock-free list Максим Хижинский, CoreHard.by Минск, 2016 Atomic примитивы ● atomic load/store ● atomic CAS Safe memory reclamation schema (Hazard Pointers, uRCU)+Решили: ● Проблему удаления узлов (delete) ● ABA-проблему Открытая проблема: параллельный insert и erase
  • 16. Lock-free list: insert/eraseLock-free list: insert/erase A: find key 3 H T52 8 prev 3 found B: find insert pos for key 4 iprev inext A: erase key 3 H T52 83 prev->next_.CAS( found, next ) next B: insert key 4 H T52 83 4 iprev->next_.CAS( inext, new_item ) local vars Максим Хижинский, CoreHard.by Минск, 2016
  • 17. Marked pointerMarked pointer [ T.Harris, 2001 ] Двухфазное удаление: ● Логическое удаление — помечаем элемент ● Физическое удаление — исключаем элемент В качестве метки используем младший бит указателя Максим Хижинский, CoreHard.by Минск, 2016
  • 18. Lock-free list: marked pointerLock-free list: marked pointer H T52 8 prev 3 found iprev inext nextA: erase B: insert A: Logical deletion - mark item found H T52 83 found->next_.CAS( next, next | 1 ) B: iprev->next_.CAS( inext, new_item ) - failed!!! A: Physical deletion - unlink item found H T52 83 prev->next_.CAS( found, next ) Максим Хижинский, CoreHard.by Минск, 2016
  • 19. ИтераторыИтераторы 11 Выдача итератора наружу — фактически, ссылки на элемент списка но - элемент в любой момент может быть удален Требования и контраргументы for (auto it = list.begin(); it != list.end(); ++it) it->do_something(); Максим Хижинский, CoreHard.by Минск, 2016
  • 20. guarded_ptrguarded_ptr template <typename T> struct guarded_ptr { hp_guard hp; // защищает элемент T * ptr; // элемент списка guarded_ptr(std::atomic<T *>& p) { ptr = hp.protect( p ); } ~guarded_ptr() { hp.clear(); } T * operator ->() const { return ptr; } explicit operator bool() const { return ptr != nullptr; } }; // Пример guarded_ptr gp = list.find( key ); if ( gp ) { // можно безопасно обращаться к полям T через gp } Максим Хижинский, CoreHard.by Минск, 2016
  • 21. ИтераторыИтераторы но - список постоянно изменяется 22Обход всех элементов списка for (auto it = list.begin(); it != list.end(); ++it) it->do_something(); Требования и контраргументы Максим Хижинский, CoreHard.by Минск, 2016
  • 22. ИтераторыИтераторы auto it = list.begin() it == list.end() ++it; ... ++it; H T inserted removed stable Максим Хижинский, CoreHard.by Минск, 2016
  • 24. Iterable lock-free listIterable lock-free list H T 2 4 5 8 Элементы списка хранят указатели на данные При удалении ключа обнуляется указатель, сам элемент списка остается H T 2 4 5 8 struct node { std::atomic<node *> next; std::atomic<T *> data; };Максим Хижинский, CoreHard.by Минск, 2016
  • 25. Iterable lock-free listIterable lock-free list class iterator { node * node; guarded_ptr<T> data; // текущий элемент public: iterator& operator++() { while ( node ) { node = node->next.load(); // не требует защиты if ( !node ) break; data.ptr = data.hp.protect(node->data.load()); if ( data.ptr ) break; } return *this; } T* operator ->() { return data.ptr; } T& operator *() { return *data.ptr; } }; Максим Хижинский, CoreHard.by Минск, 2016