Download - Неблокирующая синхронизация
![Page 1: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/1.jpg)
Неблокирующая синхронизация
Владимир Озеров
GridGain
![Page 2: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/2.jpg)
План
2
• Мотивация
• Структура
• Производительность
![Page 3: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/3.jpg)
Кто?
3
![Page 4: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/4.jpg)
План
4
• Мотивация
• Структура
• Производительность
![Page 5: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/5.jpg)
Мотивация: определения
5
• BLOCKING – один поток может не давать работать другим потокам неограниченно долго
![Page 6: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/6.jpg)
Мотивация: определения
6
• BLOCKING – один поток может не давать работать другим потокам неограниченно долго
• NON-BLOCKING = !BLOCKING
![Page 7: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/7.jpg)
Мотивация: безопасность
7
![Page 8: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/8.jpg)
Мотивация: безопасность в Java
8
1: lock.lock();
2:
3: try {
4: doSomething();
5: } finally {
6: lock.unlock();
7: }
![Page 9: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/9.jpg)
Мотивация: безопасность в Java
9
1: lock.lock();
2:
3: try {
4: doSomething();
5: } finally {
6: lock.unlock();
7: } Stack overflow!
http://openjdk.java.net/jeps/270
![Page 10: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/10.jpg)
Мотивация: безопасность в .NET :-)
10
1: try {
2: } finally {
3: lock.lock();
4:
5: try {
6: doSomething();
7: } finally {
8: lock.unlock();
9: }
10: }
MSDN: “Unexecuted finally blocks are executed before the thread is aborted.”
![Page 11: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/11.jpg)
Мотивация: инверсия приоритетов
11
![Page 12: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/12.jpg)
Мотивация: инверсия приоритетов
12
1: Connection conn = pool.acquire();
2:
3: try {
4: execute(conn);
5: } finally {
6: pool.release(conn);
7: }
![Page 13: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/13.jpg)
Мотивация: инверсия приоритетов
13
1: Connection conn = pool.tryAcquire(5000L);
2:
3: if (conn != null) {
4: ...
5: } else {
6: conn = Connection.create(...);
7: ...
8: }
![Page 14: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/14.jpg)
Мотивация: deadlocks
14
"ContainersLauncher #27":
at AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:331)
- waiting to lock <B> (AllocatorPerContext)
[3 other calls]
at LocalDirsHandlerService.getLocalPathForWrite(LocalDirsHandlerService.java:262)
- locked <A> (Configuration)
"New I/O server worker #1-3":
at Configuration.getProps(Configuration.java:1373)
- waiting to lock <A> (Configuration)
[7 other calls]
at AllocatorPerContext.getLocalPathToRead(LocalDirAllocator.java:425)
- locked <B> (AllocatorPerContext)
![Page 15: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/15.jpg)
Мотивация: производительность
15
BLOCKING IDEAL
![Page 16: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/16.jpg)
Мотивация: итоги
16
БезопасностьИнверсия приоритетовDeadlock
Производительность
LowLowLow
High
![Page 17: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/17.jpg)
Мотивация: итоги
17
БезопасностьИнверсия приоритетовDeadlock
ПроизводительностьУдобство
LowLowLow
HighHigh
![Page 18: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/18.jpg)
План
18
• Мотивация
• Структура
• Производительность
![Page 19: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/19.jpg)
Структура: compare-and-set
19
1: bool CAS(T* address, T expected, T new) {
2: if (*address == expected) {
3: *address = new;
4:
5: return true;
6: } else
7: return false;
8: }
![Page 20: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/20.jpg)
Структура: compare-and-set
20
![Page 21: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/21.jpg)
Структура: atomics
21
1: synchronized (...) {
2: if (starting)
3: throw new AlreadyStartedException();
4:
5: starting = true;
6: }
7:
8: doStart();
![Page 22: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/22.jpg)
Структура: atomics
22
1: synchronized (...) {
2: if (starting)
3: throw new AlreadyStartedException();
4:
5: starting = true;
6: }
7:
8: doStart();
1: if (!starting.compareAndSet(false, true))
2: throw new AlreadyStartedException();
3:
4: doStart();
![Page 23: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/23.jpg)
Структура: races
23
![Page 24: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/24.jpg)
Структура: races
24
![Page 25: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/25.jpg)
Упрощаем: меньше shared state
25
1: volatile int a;
2: volatile int b;
![Page 26: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/26.jpg)
Упрощаем: меньше shared state
26
1: volatile int a;
2: volatile int b;
1: class State {
2: final int a;
3: final int b;
4: }
5:
6: volatile State state;
![Page 27: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/27.jpg)
Упрощаем: обратно в blocking
27
1: Node node = new Node(key, val);
2:
3: if (table.compareAndSet(index, null, node))
4: return null;
5: else {
6: Node oldNode = table.get(index);
7:
8: synchronized (oldNode) {
9: ...
10: }
11: }
ConcurrentHashMap
![Page 28: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/28.jpg)
Упрощаем: меньше гарантий
28
1: private final ConcurrentLinkedQueue queue;
2: private final LongAccumulator size;
3:
4: public boolean offer(E e) {
5: size.accumulate(1L);
6:
7: return queue.offer(e);
8: }
![Page 29: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/29.jpg)
Упрощаем: меньше гарантий
29
1: private final ConcurrentLinkedQueue queue;
2: private final LongAccumulator size;
3:
4: public boolean offer(E e) {
5: size.accumulate(1L);
6:
7: return queue.offer(e);
8: }
assert q.size() > 0 && q.peek() != null;
FAIL!
![Page 30: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/30.jpg)
Структура: lock-free
30
![Page 31: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/31.jpg)
Пример: busy lock
31
1: class BusyLock {
2: boolean tryAcquire();
3: void release();
4:
5: void block();
7: }
![Page 32: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/32.jpg)
Структура: lock-free
32
1: final AtomicInteger state = new AtomicInteger();
2:
3: boolean tryAcquire() {
4: while (true) {
5: int state0 = state.get();
6:
7: if (isBlocked(state0))
8: return false;
9:
10: if (state.compareAndSet(state0, state0 + 1)
11: return true;
12: }
13: }
![Page 33: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/33.jpg)
Структура: wait-free
33
![Page 34: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/34.jpg)
Структура: wait-free
34
1: final AtomicInteger acquired = new AtomicInteger();
2: volatile boolean blocked;
3:
4: boolean tryAcquire() {
5: acquired.incrementAndGet();
6:
7: if (blocked) {
8: acquired.decrementAndGet();
9:
10: return false;
11: }
12:
13: return true;
14: }
![Page 35: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/35.jpg)
Структура: assist
35
![Page 36: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/36.jpg)
Структура: assist
36
1: AtomicReference<Batch> batch;
2:
3: void addToBatch(Object item) {
4: while (true) {
5: Batch batch0 = batch.get();
6:
7: if (batch0.tryAdd(item))
8: return;
9:
10:
11: }
12: }
![Page 37: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/37.jpg)
Структура: assist
37
1: AtomicReference<Batch> batch;
2:
3: void addToBatch(Object item) {
4: while (true) {
5: Batch batch0 = batch.get();
6:
7: if (batch0.tryAdd(item))
8: return;
9: else
10: batch.compareAndSet(batch0, new Batch());
11: }
12: }
![Page 38: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/38.jpg)
План
38
• Мотивация
• Структура
• Производительность
![Page 39: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/39.jpg)
Производительность: latency
39
![Page 40: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/40.jpg)
Производительность: lock convoy
40
![Page 41: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/41.jpg)
Производительность: throughput
41
BLOCKING IDEAL
![Page 42: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/42.jpg)
Производительность: throughput
42
1: BusyLock lock;
2:
3: void doBenchmark() {
4: if (lock.tryAcquire()) {
5: try {
6: payload(); // e.g. consumeCPU(x)
7: } finally {
8: lock.release();
9: }
10: }
11: }
![Page 43: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/43.jpg)
Производительность: CAS
43
0
10
20
30
40
50
1 2 4 8
MO
ps\
sec
Threads
CAS
![Page 44: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/44.jpg)
Производительность: synchronized
44
0
10
20
30
40
50
1 2 4 8
MO
ps\
sec
Threads
CAS
synchronized
![Page 45: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/45.jpg)
Производительность: contention
45
CAS/increment
![Page 46: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/46.jpg)
Производительность: contention
46
CAS/increment synchronized
http://mechanical-sympathy.blogspot.ru/2013/01/further-adventures-with-cas.htmlhttp://www.intel.com/content/dam/www/public/us/en/documents/white-papers/xeon-lock-scaling-analysis-paper.pdf
![Page 47: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/47.jpg)
Производительность: batching
47
1: AtomicLong generator;
2:
3: return generator.getAndIncrement();
![Page 48: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/48.jpg)
Производительность: batching
48
1: AtomicLong generator;
2:
3: return generator.getAndIncrement();
1: AtomicLong generator;
2:
3: return generator.getAndAdd(1000);
![Page 49: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/49.jpg)
Производительность: backoff
49
1: boolean tryAcquire() {
2: for (int i = 0;; i++) {
3: ...
4:
5: if (isSpin(i))
6: for (...)
7: Runtime.getRuntime().onSpinWait();
8: else if (isYield(i))
9: Thread.sleep(0);
10: else
11: Thread.sleep(1);
12: }
13: }
![Page 50: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/50.jpg)
Производительность: backoff
50
0
10
20
30
40
50
1 2 4 8
MO
ps\
sec
Threads
CAS
CAS + backoff
![Page 51: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/51.jpg)
Производительность: no stores
51
1: volatile HashMap<K, V> map;
2:
3: V get(K key) {
4: return map.get(key);
5: }
6:
7: V put(K key, V val) {
8: synchronized (this) {
9: map = copyAndPut(key, val);
10: }
11: }
![Page 52: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/52.jpg)
Производительность: stripes
52
![Page 53: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/53.jpg)
Производительность: stripes
53
0
50
100
150
1 2 4 8
MO
ps\
sec
Threads
CAS
CAS + backoff
CAS + stripes
![Page 54: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/54.jpg)
Производительность: local state
54
![Page 55: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/55.jpg)
Производительность: консенсус
55
1: void resize(Node[] oldTable, int newSize) {
2: Node[] newTable = new Node[newSize];
3:
4: newTable.compareAndSet(oldTable, newTable);
5:
6: ...
7: }
NonBlockingHashMap
https://github.com/boundary/high-scale-lib/blob/master/src/main/java/org/cliffc/high_scale_lib/NonBlockingHashMap.java#L752
![Page 56: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/56.jpg)
Выводы
56
Мотивация:• В первую очередь – удобство и performance• Во вторую – дедлоки, priority inversion, safety
Структура:• Минимум операций над shared variables• Не удерживаем non-blocking, если оно не нужно• Гарантии: lock-free vs wait-free
Performance:• Latency: непрерывное выполнение кода потоком• Throughput: боремся с contention, а не с блокировками
![Page 57: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/57.jpg)
Ссылки
57
Площадки:• http://jsr166-concurrency.10961.n7.nabble.com/• https://groups.google.com/forum/#!forum/mechanical-sympathy
Люди:• Dmitry Vyukov – http://www.1024cores.net/• Nitsan Wakart – http://psy-lob-saw.blogspot.ru/• Martin Thompson – http://mechanical-sympathy.blogspot.ru/
Проекты:• JCTools – https://github.com/JCTools/JCTools• Agrona (Aeron) – https://github.com/real-logic/Agrona
![Page 58: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/58.jpg)
Контакты
58
Twitter:• https://twitter.com/devozerov
GitHub:• https://github.com/devozerov/ozerov_2016_jpoint
![Page 59: Неблокирующая синхронизация](https://reader033.vdocuments.site/reader033/viewer/2022061101/629b61a51261f11c2b36bbcd/html5/thumbnails/59.jpg)
59
Вопросы?