SlideShare a Scribd company logo
1 of 66
Download to read offline
Concurrent mapS
C++ Russia 2015Maxim Khizhinsky
Concurrent mapsConcurrent maps
LIBCDS
Максим Хижинский, C++ Russia 2015
Операции:
● insert( key, value )
●
erase( key )
● find( key )
План:
● Concurrent maps изнутри
●
Управление памятью в lock-free структурах
●
Lock-free ordered list и concurrent maps на его основе
● Немного о деревьях
Hash tableHash table
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X X
k1
k
k
k k
k
kk
k
k
2
3
4 5
6
7
8
9
T[7]
T[i] = std::hash( key ) % 7
Список
коллизий
Striped mapStriped map
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X X
k1
k
k
k k
k
kk
k
k
2
3
4 5
6
7
8
9
T[7]
T[i] = std::hash( key ) % 7
Striped mapStriped map
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X X
k1
k
k
k k
k
kk
k
k
2
3
4 5
6
7
8
9
T[7]
T[i] = std::hash( key ) % 7
Lock[7]
Striped map: rehashStriped map: rehash
LIBCDS
Максим Хижинский, C++ Russia 2015
1. for ( i = 0; i < L; i++ )
Lock[i].lock();
2. N := 2 * N;
3. rehash T
4. for ( i := L - 1; i >=0; --i )
Lock[i].unlock();
L — const
Initial: L = N
Rehash: N := 2N
Striped map: rehashStriped map: rehash
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X
k1
k
k
k k kkk
kk
2
3
4 5 67
89
T[8]
Lock[i] = std::hash( key ) % 4
Lock[4]
7
T[j] = std::hash( key ) % 8
Striped mapStriped map
LIBCDS
Максим Хижинский, C++ Russia 2015
Lock[i] = std::hash( key ) % L
Lock[L]
α β γ δ
Tree search
Lock-free hash tableLock-free hash table
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X X
k1
k
k
k k
k
kk
k
k
2
3
4 5
6
7
8
9
T[8]
Lock-free
список
коллизий
7
k
10
Lock-free ordered listLock-free ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
Операции:
●
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)
CAS — compare-and-swapCAS — compare-and-swap
LIBCDS
Максим Хижинский, C++ Russia 2015
template <typename T>
bool CAS( T * pAtomic, T expected, T desired )
atomically {
if ( *pAtomic == expected ) {
*pAtomic = desired;
return true;
}
else
return false;
};
Lock-free list: insertLock-free list: insert
LIBCDS
Максим Хижинский, C++ Russia 2015
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
Lock-free list: eraseLock-free list: erase
LIBCDS
Максим Хижинский, C++ Russia 2015
1. find key 3
2. prev->next_.CAS( found, next )
H T52 8
prev
3
found
H T52 83
Проблема: параллельный insert
next
Lock-free list: insert/eraseLock-free list: insert/erase
LIBCDS
Максим Хижинский, C++ Russia 2015
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
Marked pointerMarked pointer
LIBCDS
Максим Хижинский, C++ Russia 2015
[ T.Harris, 2001 ]
Двухфазное удаление:
● Логическое удаление — помечаем элемент
●
Физическое удаление — исключаем элемент
В качестве метки используем младший бит указателя
Lock-free list: marked pointerLock-free list: marked pointer
LIBCDS
Максим Хижинский, C++ Russia 2015
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 - remove item found
H T52 83
prev->next_.CAS( found, next )
Lock-free list: problemsLock-free list: problems
LIBCDS
Максим Хижинский, C++ Russia 2015
H T52 8
prev
3
found
iprev inext
nextA: erase
B: insert
iprev->next_.CAS( inext, new_item )
prev->next_.CAS( found, next )
local vars
Вдруг уже удалены?..
Lock-free list: problemsLock-free list: problems
LIBCDS
Максим Хижинский, C++ Russia 2015
Проблемы:
●
Защита локальных данных — когда элемент можно
безопасно удалить?
●
ABA-проблема
ABA-проблемаABA-проблема
LIBCDS
Максим Хижинский, C++ Russia 2015
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 мусор
SMRSMR
LIBCDS
Максим Хижинский, C++ Russia 2015
Проблемы:
● Защита локальных данных — когда элемент можно
безопасно удалить?
●
ABA-проблема
Решение:
Safe memory reclamation (SMR)
● Tagged pointers
●
Hazard Pointers
●
User-space RCU
Tagged pointersTagged pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
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
Tagged pointers: historyTagged pointers: history
LIBCDS
Максим Хижинский, C++ Russia 2015
ABA-проблема характерна только для CAS
Архитектуры процессоров
LL/SC:
●
IBM PowerPC
● MIPS
●
ARM
➢ LL — load linked
➢ SC — store conditional
bool weak_CAS( T * ptr,
T expected, T desired )
{ T cur = LL( ptr );
return cur == expected
&& SC( ptr, desired );
}
Эмуляция LL/SC на CAS
— намного труднее
CAS:
●
x86, amd64
● Sparc
●
Itanium
С++11 — только CAS
Hazard pointersHazard pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
✔ Использует только атомарные чтение/запись
 Защищает только локальные ссылки
✔ Размер массива отложенных (готовых к
удалению) элементов ограничен сверху
 Перед работой с указателем его следует
объявить как hazard
решает ABA-проблему
Физическое удаление элементов
Hazard pointersHazard pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
H T52 8
prev
3
found next
erase( Key k ) {
hp_guard h1 = get_guard();
hp_guard h2 = get_guard();
retry:
node * prev = Head;
do {
node * found = h2.protect( prev->next_);
if ( found->key == k )
if (prev->next_.CAS( found, found->next_)) {
hp_retire( found );
return true;
}
else
goto retry;
h1 = h2;
prev = found;
} while ( found->key < k );
return false;
}
Распределяем HP (TLS)
Защищаем элемент
Удаляем элемент
Hazard pointersHazard pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
P – thread count
Thread 0
Thread HP Manager
0
1
…
K - 1
HP[K]
0
1
2
…
R - 1
Retired[R]
Hazard Pointer Singleton
Thread
1
Thread
P - 1
K = 4 R = 2 KP
<K,P, R> : R > K * P
Hazard PointersHazard Pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
Объявление Hazard Pointer'а – защита локальной ссылки
class hp_guard {
void * hp;
// ...
};
T * hp_guard::protect(
std::atomic<T*>& what) {
T * t;
do {
hp = t = what.load(std::memory_order_relaxed);
} while (t != what.load(std::memory_order_acquire));
return t;
}
0
1
…
K - 1
HP[K]
Hazard PointersHazard Pointers
LIBCDS
Максим Хижинский, C++ Russia 2015
Удаление элемента
void hp_retire( T * what ) {
push what to current_thread.Retired array
if ( current_thread.Retired is full )
hp.Scan( current_thread );
}
void hp::Scan() {
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;
}
<K,P, R> : R > K * P
0
1
2
…
R - 1
Retired[R]
0
1
…
K - 1
HP[K]
User-space Read-Copy UpdateUser-space Read-Copy Update
LIBCDS
Максим Хижинский, C++ Russia 2015
✔ RCU — метод синхронизации:
RCU.lock() / RCU.unlock()
✔ Разработан для почти-read-only данных (map, set)
✔ Очень легкие read-side lock
✔ Удаление элемента — ожидание окончания эпохи
решает ABA-проблему
Физическое удаление элементов
RCU.lock(): ничего не блокирует
Объявляет, что поток входит в
текущую RCU-эпоху
User-space RCUUser-space RCU
LIBCDS
Максим Хижинский, C++ Russia 2015
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
Lock-free hash tableLock-free hash table
LIBCDS
Максим Хижинский, C++ Russia 2015
0 1 2 3 4 5 6
X X X
k1
k
k
k k
k
kk
k
k
2
3
4 5
6
7
8
9
T[8]
Lock-free
cписок:
HP/RCU
+ marked
pointers
7
k
10
Hash table + Lock-free ordered list
No rehashing
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
Rehashing приводит к перераспределению
элементов между buckets
0 1
2
4
6
3
5
0 1 2 3
2 354
6
Key % 2 Key % 4
Вместо того, чтобы перемещать
элементы между buckets, будем
перемещать buckets между
элементами
[ Nir Shavit, 2003 ]
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
N = 2 size() = 4
Load factor L: size() / N ≤ L
Если L = 2, то вставка нового элемента приводит к увеличению
hash table
Hash table
Lock-free ordered list
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
N = 4
Hash table
Insert
T[2] = null
T[3] = null
10
T[i]: i = hash % N
10 % 4 = 2 — T[2] не инициализирован
Нужно вставить новый sentinel node
Куда вставлять?..
2
10
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
N = 4
Hash table
Insert
T[2] = null
T[3] = null
10
2
Split bucket
Bucket = hash % 2
m + 1
Parent_bucket Parent_bucket + 2
m
= 10 % 4
10 % 4, m = 12
Parent_bucket = 0
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
N = 4
Hash table
Insert
T[2] = null
T[3] = null
10
2
Split bucket
Bucket = hash % 2
m + 1
Parent_bucket Parent_bucket + 2
m
= 10 % 4
10 % 4, m = 12
Parent_bucket = 0
0000 1000 0010 0001 1001 1101
0010
Арифметика
по модулю
2
p
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
N = 4
Hash table
Insert
T[2] = null
T[3] = null
10
2
Split bucket
Bucket = hash % 2
m + 1
Parent_bucket Parent_bucket + 2
m
= 10 % 4
10 % 4, m = 12
Parent_bucket = 0
0000 0001 0100 1000 1001 1011
0100
Инвертируем
порядок бит!
Отсортирован!
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
template <class Key, class T>
struct split_list_node
{
Key key;
uint key_hash; // = std::hash(key)
uint shah; // = invert( key_hash ) - для сортировки
T data;
};
Уже есть!!!
parent_bucket
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
Hash table
Insert
T[2] = null
T[3] = null
2
0000 0 0001 1 0100 1 1000 0 1001 1 1011 1
Надо различать sentinel и
regular node.
msb(key_hash) = 1 — regular → lsb( shah ) = 1
msb(key_hash) = 0 — sentinel →lsb( shah ) = 0
0100 0
parent_bucket
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
Hash table
Insert
T[2]
T[3] = null
2
0000 0 0001 1 0100 1 1000 0 1001 1 1011 1
0100 0
2
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
0 8 2 1 9 13
T[0]
T[1]
k iSentinel node Regular node
Hash table
Insert
T[2]
T[3] = null
0000 0 0001 1 0100 1 1000 0 1001 1 1011 10100 0
2
10
0101 1
0101 1
10
Bucket = 10 % 4 = 2
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
Удаление — как из обычного lock-free списка
Sentinel node никогда не удаляются
1: Logical deletion - mark item
52 83
found->next_.CAS( next, next | 1 )
2: Physical deletion - unlink item
52 83
Split-ordered listSplit-ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
T[0]
T[1]
. . . .
T[N-1]
T[N]
seg0
seg1
. . . .
null
Segment[M]
T[0]
T[1]
. . . .
T[N-1]
T[N]
T[0]
T[1]
. . . .
T[N-1]
T[N]
Статический
массив
сегментов
Сегментная организация hash table
Сегмент – старшие биты хеша
T[i] – младшие N бит хеша
Динамическое расширение
Lock-free ordered listLock-free ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
X10 15 23 34 5542
Complexity O(N)
Что ещё можно сделать из lock-free ordered list?
✔ Простой hash map — без расширения
✔ Split-ordered list
find(34)
Lock-free ordered listLock-free ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
X10 15 23 34 5542
Complexity O(N/2)
X
Lock-free ordered listLock-free ordered list
LIBCDS
Максим Хижинский, C++ Russia 2015
X10 15 23 34 5542
Complexity O(N/4)
X
X
Skip listSkip list
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
[ W.Pugh, 1990 ]
Skip listSkip list
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
23
Tower
h = 3
Вероятностная структура данных:
P[ h == 1 ] = 1/2
P[ h == k ] = 1/2
k
, 0 < k < 32
h = lsb( rand() )
O(log(N))
Skip list: insertSkip list: insert
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
Поиск позиции: формируем массив prev[]
Skip list: insertSkip list: insert
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
Связываем в список на уровне 0
Skip list: insertSkip list: insert
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
Связываем в список на уровне 1, 2, …
снизу вверх
Skip list: eraseSkip list: erase
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
Двухфазное: 1. Logical deletion — mark
сверху вниз
Skip list: eraseSkip list: erase
LIBCDS
Максим Хижинский, C++ Russia 2015
X
X
X
X
X
X
X
X10 15 23 34 5542
Head Tail
Фаза 2. Physical deletion — unlink
сверху вниз
Skip listSkip list
LIBCDS
Максим Хижинский, C++ Russia 2015
Особенности:
Отсортированный контейнер
get_max(), get_min()
Можно использовать как priority queue
Сложность поиска: O(log N)
Hazard Pointer: для max height = 32 требует
min 64 hazard pointer'ов
Требует эффективной реализации tower
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
«Прямой» lock-free подход приводит к очень сложным
алгоритмам.
Non-blocking подход дает менее сложные алгоритмы
Routing nodes - только ключи
Leaf nodes - данные
Leaf-oriented tree
Основная цель: lock-free / wait-free find()
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Thread A: erase(15)
Thread B: erase(27)
10
5 20
3015
27 45
Error!!!
Достижимый
узел
Конкурентное CAS-based удаление
CAS
CAS
Должно быть
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Thread A: erase(27)
Thread B: insert(29)
10
5 20
3015
27
45
Error!!!
Недостижимые
узлы
Конкурентное CAS-based удаление + вставка
CAS
29
29
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
Routing node
Left child Right child
State
Key
IFlag DFlag
MarkClean (default)
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Insert 29
1 30.State.CAS( Clean, IFlag)
10
5 20
3015
27
4527
29
2 Insert
30.left.CAS( )27 27
10
5 20
3015
27
4527
29
3 30.State.CAS( IFlag, Clean )
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Erase 27
1 20.State.CAS( Clean, DFlag)
10
5 20
3015
27 45
2 Mark 30
30.State.CAS(
Clean, Mark)
10
5 20
3015
27 45
3 Delete
20.right.CAS( )30 45
10
5 20
3015
27 45
4 20.State.CAS(
Dflag, Clean)
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Thread A: erase(15)
Thread B: erase(27)
10
5 20
3015
27 45
Error!!!
Достижимый
узел
Конкурентное CAS-based удаление
CAS
CAS
Должно быть
Конкуренция
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
10
5 20
3015
27 45
Thread A: erase(15)
Thread B: erase(27)
Конкурентное CAS-based удаление
A
BA
10
5 20
3015
27 45
A
A
Выиграл A
10
5 20
3015
27 45
A
Выиграл B
B
B
B: повтор
поиска 27
A: unflag +
повтор
поиска 15
Binary search treeBinary search tree
LIBCDS
Максим Хижинский, C++ Russia 2015
find() - lock-free
insert(), erase() - non-blocked
Характеристики:
Сложность:
O(log(N)) — для случайных ключей
O(N) — в худшем случае
libcdslibcds
LIBCDS
Максим Хижинский, C++ Russia 2015
https://github.com/khizmax/libcds
Все это, а также многое другое, можно найти здесь:
PerformancePerformance
LIBCDS
Максим Хижинский, C++ Russia 2015
Intel Dual Xeon X5670 2.93 GHz 12 cores 24 threads / 24 GB RAM
Questions?..Questions?..
Максим Хижинский, C++ Russia 2015
Concurrent mapsConcurrent maps
Максим Хижинский, C++ Russia 2015
Спасибо за внимание!
libcds.dev@gmail.com
https://github.com/khizmax/libcds

More Related Content

What's hot

Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsPlatonov Sergey
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаAndrey Karpov
 
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...Iosif Itkin
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияAlexey Paznikov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Mikhail Matrosov
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаPositive Hack Days
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыcorehard_by
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 

What's hot (20)

Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программиста
 
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Python
PythonPython
Python
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 

Viewers also liked

Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверPlatonov Sergey
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and deletePlatonov Sergey
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++NextSergey Platonov
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерSergey Platonov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиvictor-yastrebov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3Platonov Sergey
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеIlia Shishkov
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines Sergey Zubkov
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projectscorehard_by
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done rightPlatonov Sergey
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit TestingDmitry Vyukov
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейSergey Platonov
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratchPlatonov Sergey
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsPlatonov Sergey
 

Viewers also liked (20)

Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 
Multithreading done right
Multithreading done rightMultithreading done right
Multithreading done right
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
 
Agile At Intel
Agile At IntelAgile At Intel
Agile At Intel
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratch
 
Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
 

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

Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Platonov Sergey
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...corehard_by
 
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
 
Когда в C# не хватает C++ . Часть 3.
Когда в C# не хватает C++. Часть 3. Когда в C# не хватает C++. Часть 3.
Когда в C# не хватает C++ . Часть 3. Mikhail Shcherbakov
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Fwdays
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Александр Сомов "C++: препроцессор, компилятор, компоновщик"
Александр Сомов "C++: препроцессор, компилятор, компоновщик"Александр Сомов "C++: препроцессор, компилятор, компоновщик"
Александр Сомов "C++: препроцессор, компилятор, компоновщик"Yandex
 
Правильная организация клиент-карточного взаимодействия — Антон Корзунов
Правильная организация клиент-карточного взаимодействия — Антон КорзуновПравильная организация клиент-карточного взаимодействия — Антон Корзунов
Правильная организация клиент-карточного взаимодействия — Антон КорзуновYandex
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоCodeFest
 
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)Ontico
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...Mail.ru Group
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and ClojureVasil Remeniuk
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Yandex
 

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

Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
 
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
 
Когда в C# не хватает C++ . Часть 3.
Когда в C# не хватает C++. Часть 3. Когда в C# не хватает C++. Часть 3.
Когда в C# не хватает C++ . Часть 3.
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Lektsia 9
Lektsia 9Lektsia 9
Lektsia 9
 
OpenACC short review
OpenACC short reviewOpenACC short review
OpenACC short review
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Александр Сомов "C++: препроцессор, компилятор, компоновщик"
Александр Сомов "C++: препроцессор, компилятор, компоновщик"Александр Сомов "C++: препроцессор, компилятор, компоновщик"
Александр Сомов "C++: препроцессор, компилятор, компоновщик"
 
Правильная организация клиент-карточного взаимодействия — Антон Корзунов
Правильная организация клиент-карточного взаимодействия — Антон КорзуновПравильная организация клиент-карточного взаимодействия — Антон Корзунов
Правильная организация клиент-карточного взаимодействия — Антон Корзунов
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван Панченко
 
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)
Тонкости работы трассирующего JIT-компилятора / Антон Солдатов (IPONWEB)
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and Clojure
 
Algo 00
Algo 00Algo 00
Algo 00
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 

More from 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
 
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
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtPlatonov Sergey
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Platonov 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
 
Библиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLБиблиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLPlatonov Sergey
 

More from Platonov Sergey (20)

Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
 
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++ тонкости и нюансы
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система Qt
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 
Библиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLБиблиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLL
 

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

  • 1. Concurrent mapS C++ Russia 2015Maxim Khizhinsky
  • 2. Concurrent mapsConcurrent maps LIBCDS Максим Хижинский, C++ Russia 2015 Операции: ● insert( key, value ) ● erase( key ) ● find( key ) План: ● Concurrent maps изнутри ● Управление памятью в lock-free структурах ● Lock-free ordered list и concurrent maps на его основе ● Немного о деревьях
  • 3. Hash tableHash table LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X X k1 k k k k k kk k k 2 3 4 5 6 7 8 9 T[7] T[i] = std::hash( key ) % 7 Список коллизий
  • 4. Striped mapStriped map LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X X k1 k k k k k kk k k 2 3 4 5 6 7 8 9 T[7] T[i] = std::hash( key ) % 7
  • 5. Striped mapStriped map LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X X k1 k k k k k kk k k 2 3 4 5 6 7 8 9 T[7] T[i] = std::hash( key ) % 7 Lock[7]
  • 6. Striped map: rehashStriped map: rehash LIBCDS Максим Хижинский, C++ Russia 2015 1. for ( i = 0; i < L; i++ ) Lock[i].lock(); 2. N := 2 * N; 3. rehash T 4. for ( i := L - 1; i >=0; --i ) Lock[i].unlock();
  • 7. L — const Initial: L = N Rehash: N := 2N Striped map: rehashStriped map: rehash LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X k1 k k k k kkk kk 2 3 4 5 67 89 T[8] Lock[i] = std::hash( key ) % 4 Lock[4] 7 T[j] = std::hash( key ) % 8
  • 8. Striped mapStriped map LIBCDS Максим Хижинский, C++ Russia 2015 Lock[i] = std::hash( key ) % L Lock[L] α β γ δ Tree search
  • 9. Lock-free hash tableLock-free hash table LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X X k1 k k k k k kk k k 2 3 4 5 6 7 8 9 T[8] Lock-free список коллизий 7 k 10
  • 10. Lock-free ordered listLock-free ordered list LIBCDS Максим Хижинский, C++ Russia 2015 Операции: ● 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)
  • 11. CAS — compare-and-swapCAS — compare-and-swap LIBCDS Максим Хижинский, C++ Russia 2015 template <typename T> bool CAS( T * pAtomic, T expected, T desired ) atomically { if ( *pAtomic == expected ) { *pAtomic = desired; return true; } else return false; };
  • 12. Lock-free list: insertLock-free list: insert LIBCDS Максим Хижинский, C++ Russia 2015 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
  • 13. Lock-free list: eraseLock-free list: erase LIBCDS Максим Хижинский, C++ Russia 2015 1. find key 3 2. prev->next_.CAS( found, next ) H T52 8 prev 3 found H T52 83 Проблема: параллельный insert next
  • 14. Lock-free list: insert/eraseLock-free list: insert/erase LIBCDS Максим Хижинский, C++ Russia 2015 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
  • 15. Marked pointerMarked pointer LIBCDS Максим Хижинский, C++ Russia 2015 [ T.Harris, 2001 ] Двухфазное удаление: ● Логическое удаление — помечаем элемент ● Физическое удаление — исключаем элемент В качестве метки используем младший бит указателя
  • 16. Lock-free list: marked pointerLock-free list: marked pointer LIBCDS Максим Хижинский, C++ Russia 2015 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 - remove item found H T52 83 prev->next_.CAS( found, next )
  • 17. Lock-free list: problemsLock-free list: problems LIBCDS Максим Хижинский, C++ Russia 2015 H T52 8 prev 3 found iprev inext nextA: erase B: insert iprev->next_.CAS( inext, new_item ) prev->next_.CAS( found, next ) local vars Вдруг уже удалены?..
  • 18. Lock-free list: problemsLock-free list: problems LIBCDS Максим Хижинский, C++ Russia 2015 Проблемы: ● Защита локальных данных — когда элемент можно безопасно удалить? ● ABA-проблема
  • 19. ABA-проблемаABA-проблема LIBCDS Максим Хижинский, C++ Russia 2015 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 мусор
  • 20. SMRSMR LIBCDS Максим Хижинский, C++ Russia 2015 Проблемы: ● Защита локальных данных — когда элемент можно безопасно удалить? ● ABA-проблема Решение: Safe memory reclamation (SMR) ● Tagged pointers ● Hazard Pointers ● User-space RCU
  • 21. Tagged pointersTagged pointers LIBCDS Максим Хижинский, C++ Russia 2015 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
  • 22. Tagged pointers: historyTagged pointers: history LIBCDS Максим Хижинский, C++ Russia 2015 ABA-проблема характерна только для CAS Архитектуры процессоров LL/SC: ● IBM PowerPC ● MIPS ● ARM ➢ LL — load linked ➢ SC — store conditional bool weak_CAS( T * ptr, T expected, T desired ) { T cur = LL( ptr ); return cur == expected && SC( ptr, desired ); } Эмуляция LL/SC на CAS — намного труднее CAS: ● x86, amd64 ● Sparc ● Itanium С++11 — только CAS
  • 23. Hazard pointersHazard pointers LIBCDS Максим Хижинский, C++ Russia 2015 ✔ Использует только атомарные чтение/запись  Защищает только локальные ссылки ✔ Размер массива отложенных (готовых к удалению) элементов ограничен сверху  Перед работой с указателем его следует объявить как hazard решает ABA-проблему Физическое удаление элементов
  • 24. Hazard pointersHazard pointers LIBCDS Максим Хижинский, C++ Russia 2015 H T52 8 prev 3 found next erase( Key k ) { hp_guard h1 = get_guard(); hp_guard h2 = get_guard(); retry: node * prev = Head; do { node * found = h2.protect( prev->next_); if ( found->key == k ) if (prev->next_.CAS( found, found->next_)) { hp_retire( found ); return true; } else goto retry; h1 = h2; prev = found; } while ( found->key < k ); return false; } Распределяем HP (TLS) Защищаем элемент Удаляем элемент
  • 25. Hazard pointersHazard pointers LIBCDS Максим Хижинский, C++ Russia 2015 P – thread count Thread 0 Thread HP Manager 0 1 … K - 1 HP[K] 0 1 2 … R - 1 Retired[R] Hazard Pointer Singleton Thread 1 Thread P - 1 K = 4 R = 2 KP <K,P, R> : R > K * P
  • 26. Hazard PointersHazard Pointers LIBCDS Максим Хижинский, C++ Russia 2015 Объявление Hazard Pointer'а – защита локальной ссылки class hp_guard { void * hp; // ... }; T * hp_guard::protect( std::atomic<T*>& what) { T * t; do { hp = t = what.load(std::memory_order_relaxed); } while (t != what.load(std::memory_order_acquire)); return t; } 0 1 … K - 1 HP[K]
  • 27. Hazard PointersHazard Pointers LIBCDS Максим Хижинский, C++ Russia 2015 Удаление элемента void hp_retire( T * what ) { push what to current_thread.Retired array if ( current_thread.Retired is full ) hp.Scan( current_thread ); } void hp::Scan() { 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; } <K,P, R> : R > K * P 0 1 2 … R - 1 Retired[R] 0 1 … K - 1 HP[K]
  • 28. User-space Read-Copy UpdateUser-space Read-Copy Update LIBCDS Максим Хижинский, C++ Russia 2015 ✔ RCU — метод синхронизации: RCU.lock() / RCU.unlock() ✔ Разработан для почти-read-only данных (map, set) ✔ Очень легкие read-side lock ✔ Удаление элемента — ожидание окончания эпохи решает ABA-проблему Физическое удаление элементов RCU.lock(): ничего не блокирует Объявляет, что поток входит в текущую RCU-эпоху
  • 29. User-space RCUUser-space RCU LIBCDS Максим Хижинский, C++ Russia 2015 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
  • 30. Lock-free hash tableLock-free hash table LIBCDS Максим Хижинский, C++ Russia 2015 0 1 2 3 4 5 6 X X X k1 k k k k k kk k k 2 3 4 5 6 7 8 9 T[8] Lock-free cписок: HP/RCU + marked pointers 7 k 10 Hash table + Lock-free ordered list No rehashing
  • 31. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 Rehashing приводит к перераспределению элементов между buckets 0 1 2 4 6 3 5 0 1 2 3 2 354 6 Key % 2 Key % 4 Вместо того, чтобы перемещать элементы между buckets, будем перемещать buckets между элементами [ Nir Shavit, 2003 ]
  • 32. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node N = 2 size() = 4 Load factor L: size() / N ≤ L Если L = 2, то вставка нового элемента приводит к увеличению hash table Hash table Lock-free ordered list
  • 33. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node N = 4 Hash table Insert T[2] = null T[3] = null 10 T[i]: i = hash % N 10 % 4 = 2 — T[2] не инициализирован Нужно вставить новый sentinel node Куда вставлять?.. 2 10
  • 34. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node N = 4 Hash table Insert T[2] = null T[3] = null 10 2 Split bucket Bucket = hash % 2 m + 1 Parent_bucket Parent_bucket + 2 m = 10 % 4 10 % 4, m = 12 Parent_bucket = 0
  • 35. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node N = 4 Hash table Insert T[2] = null T[3] = null 10 2 Split bucket Bucket = hash % 2 m + 1 Parent_bucket Parent_bucket + 2 m = 10 % 4 10 % 4, m = 12 Parent_bucket = 0 0000 1000 0010 0001 1001 1101 0010 Арифметика по модулю 2 p
  • 36. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node N = 4 Hash table Insert T[2] = null T[3] = null 10 2 Split bucket Bucket = hash % 2 m + 1 Parent_bucket Parent_bucket + 2 m = 10 % 4 10 % 4, m = 12 Parent_bucket = 0 0000 0001 0100 1000 1001 1011 0100 Инвертируем порядок бит! Отсортирован!
  • 37. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 template <class Key, class T> struct split_list_node { Key key; uint key_hash; // = std::hash(key) uint shah; // = invert( key_hash ) - для сортировки T data; };
  • 38. Уже есть!!! parent_bucket Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node Hash table Insert T[2] = null T[3] = null 2 0000 0 0001 1 0100 1 1000 0 1001 1 1011 1 Надо различать sentinel и regular node. msb(key_hash) = 1 — regular → lsb( shah ) = 1 msb(key_hash) = 0 — sentinel →lsb( shah ) = 0 0100 0
  • 39. parent_bucket Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node Hash table Insert T[2] T[3] = null 2 0000 0 0001 1 0100 1 1000 0 1001 1 1011 1 0100 0 2
  • 40. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 0 8 2 1 9 13 T[0] T[1] k iSentinel node Regular node Hash table Insert T[2] T[3] = null 0000 0 0001 1 0100 1 1000 0 1001 1 1011 10100 0 2 10 0101 1 0101 1 10 Bucket = 10 % 4 = 2
  • 41. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 Удаление — как из обычного lock-free списка Sentinel node никогда не удаляются 1: Logical deletion - mark item 52 83 found->next_.CAS( next, next | 1 ) 2: Physical deletion - unlink item 52 83
  • 42. Split-ordered listSplit-ordered list LIBCDS Максим Хижинский, C++ Russia 2015 T[0] T[1] . . . . T[N-1] T[N] seg0 seg1 . . . . null Segment[M] T[0] T[1] . . . . T[N-1] T[N] T[0] T[1] . . . . T[N-1] T[N] Статический массив сегментов Сегментная организация hash table Сегмент – старшие биты хеша T[i] – младшие N бит хеша Динамическое расширение
  • 43. Lock-free ordered listLock-free ordered list LIBCDS Максим Хижинский, C++ Russia 2015 X10 15 23 34 5542 Complexity O(N) Что ещё можно сделать из lock-free ordered list? ✔ Простой hash map — без расширения ✔ Split-ordered list find(34)
  • 44. Lock-free ordered listLock-free ordered list LIBCDS Максим Хижинский, C++ Russia 2015 X10 15 23 34 5542 Complexity O(N/2) X
  • 45. Lock-free ordered listLock-free ordered list LIBCDS Максим Хижинский, C++ Russia 2015 X10 15 23 34 5542 Complexity O(N/4) X X
  • 46. Skip listSkip list LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail [ W.Pugh, 1990 ]
  • 47. Skip listSkip list LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 23 Tower h = 3 Вероятностная структура данных: P[ h == 1 ] = 1/2 P[ h == k ] = 1/2 k , 0 < k < 32 h = lsb( rand() ) O(log(N))
  • 48. Skip list: insertSkip list: insert LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail Поиск позиции: формируем массив prev[]
  • 49. Skip list: insertSkip list: insert LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail Связываем в список на уровне 0
  • 50. Skip list: insertSkip list: insert LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail Связываем в список на уровне 1, 2, … снизу вверх
  • 51. Skip list: eraseSkip list: erase LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail Двухфазное: 1. Logical deletion — mark сверху вниз
  • 52. Skip list: eraseSkip list: erase LIBCDS Максим Хижинский, C++ Russia 2015 X X X X X X X X10 15 23 34 5542 Head Tail Фаза 2. Physical deletion — unlink сверху вниз
  • 53. Skip listSkip list LIBCDS Максим Хижинский, C++ Russia 2015 Особенности: Отсортированный контейнер get_max(), get_min() Можно использовать как priority queue Сложность поиска: O(log N) Hazard Pointer: для max height = 32 требует min 64 hazard pointer'ов Требует эффективной реализации tower
  • 54. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 «Прямой» lock-free подход приводит к очень сложным алгоритмам. Non-blocking подход дает менее сложные алгоритмы Routing nodes - только ключи Leaf nodes - данные Leaf-oriented tree Основная цель: lock-free / wait-free find()
  • 55. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Thread A: erase(15) Thread B: erase(27) 10 5 20 3015 27 45 Error!!! Достижимый узел Конкурентное CAS-based удаление CAS CAS Должно быть
  • 56. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Thread A: erase(27) Thread B: insert(29) 10 5 20 3015 27 45 Error!!! Недостижимые узлы Конкурентное CAS-based удаление + вставка CAS 29 29
  • 57. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 Routing node Left child Right child State Key IFlag DFlag MarkClean (default)
  • 58. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Insert 29 1 30.State.CAS( Clean, IFlag) 10 5 20 3015 27 4527 29 2 Insert 30.left.CAS( )27 27 10 5 20 3015 27 4527 29 3 30.State.CAS( IFlag, Clean )
  • 59. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Erase 27 1 20.State.CAS( Clean, DFlag) 10 5 20 3015 27 45 2 Mark 30 30.State.CAS( Clean, Mark) 10 5 20 3015 27 45 3 Delete 20.right.CAS( )30 45 10 5 20 3015 27 45 4 20.State.CAS( Dflag, Clean)
  • 60. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Thread A: erase(15) Thread B: erase(27) 10 5 20 3015 27 45 Error!!! Достижимый узел Конкурентное CAS-based удаление CAS CAS Должно быть
  • 61. Конкуренция Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 10 5 20 3015 27 45 Thread A: erase(15) Thread B: erase(27) Конкурентное CAS-based удаление A BA 10 5 20 3015 27 45 A A Выиграл A 10 5 20 3015 27 45 A Выиграл B B B B: повтор поиска 27 A: unflag + повтор поиска 15
  • 62. Binary search treeBinary search tree LIBCDS Максим Хижинский, C++ Russia 2015 find() - lock-free insert(), erase() - non-blocked Характеристики: Сложность: O(log(N)) — для случайных ключей O(N) — в худшем случае
  • 63. libcdslibcds LIBCDS Максим Хижинский, C++ Russia 2015 https://github.com/khizmax/libcds Все это, а также многое другое, можно найти здесь:
  • 64. PerformancePerformance LIBCDS Максим Хижинский, C++ Russia 2015 Intel Dual Xeon X5670 2.93 GHz 12 cores 24 threads / 24 GB RAM
  • 66. Concurrent mapsConcurrent maps Максим Хижинский, C++ Russia 2015 Спасибо за внимание! libcds.dev@gmail.com https://github.com/khizmax/libcds