Top Banner
Атомики, CAS и неблокирующие алгоритмы Алексей Федоров, ОК @23derevo
55
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Atomics, CAS and Nonblocking algorithms

Атомики, CAS и неблокирующие алгоритмы Алексей Федоров, ОК

@23derevo

Page 2: Atomics, CAS and Nonblocking algorithms

@23derevo �  Oracle — 2011–2014

�  Java Compatibility Kit (JCK)

�  OK.ru — since 2014 — Technology Evangelist

�  JUG.ru Group �  JUG.ru & CodeFreeze — since 2012 �  JPoint & Joker — since 2013 �  Mobius & .NEXT — since 2014

2

Page 3: Atomics, CAS and Nonblocking algorithms

3

Page 4: Atomics, CAS and Nonblocking algorithms

О чем этот доклад

4

Page 5: Atomics, CAS and Nonblocking algorithms

О чем этот доклад

5

Page 6: Atomics, CAS and Nonblocking algorithms

Модели �  Модель с разделяемой памятью

�  Регистры � Операции: read, write

�  Удобно программировать, все привыкли

�  Модель с передачей сообщений �  Послать сообщение �  Похожа на то, как реально работает железо

6

Page 7: Atomics, CAS and Nonblocking algorithms

Терминология

�  Нет устоявшейся терминологии

�  Термины:

�  Parallel �  Concurrent �  Distributed

7

Page 8: Atomics, CAS and Nonblocking algorithms

Виды параллелизма �  На уровне операционной системы

�  На уровне одной программы / процесса

8

Page 9: Atomics, CAS and Nonblocking algorithms

Параллелизм — ОС

�  Слушать музыку и переписываться в фейсбуке в Одноклассниках

�  При зависании одной программы другие продолжают работать

�  и т.п.

9

Page 10: Atomics, CAS and Nonblocking algorithms

Преимущества параллелизма �  Использование нескольких ядер/процессоров

�  Да и на 1 ядре тоже! (async I/O)

�  Простота моделирования �  Абстракция: фреймворк забирает сложность

�  Упрощенная обработка асинхронных событий

�  Более отзывчивые интерфейсы пользователя �  Event Dispatch Thread (EDT), async calls

10

Page 11: Atomics, CAS and Nonblocking algorithms

Параллелизм на уровне отдельно взятой программы �  Эффективное использование ресурсов

�  Удобство, простота написания кода

�  Справедливость �  Обработка запросов пользователей на серверах соцсети с одинаковым приоритетом

�  Читатели и писатели � Fairness (честность)

11

Page 12: Atomics, CAS and Nonblocking algorithms

Честность

12

Page 13: Atomics, CAS and Nonblocking algorithms

Честность

13

Lock lock = new ReentrantLock(true);

Page 14: Atomics, CAS and Nonblocking algorithms

Честность

14

Lock lock = new ReentrantLock(true);

Page 15: Atomics, CAS and Nonblocking algorithms

Честность

15

Page 16: Atomics, CAS and Nonblocking algorithms

Блокировки �  java.util.concurrent — since Java 5

�  Lock —> ReentrantLock �  ReadWriteLock —> ReentrantReadWriteLock �  StampedLock — since Java 8

�  Synchronized method / section

�  wait() / notify() / notifyAll()

16

Page 17: Atomics, CAS and Nonblocking algorithms

Блокировки �  java.util.concurrent

�  Lock —> ReentrantLock �  ReadWriteLock —> ReentrantReadWriteLock

�  Syncronized method / section

�  wait() / notify() / notifyAll()

17

Общее: ожидание

Page 18: Atomics, CAS and Nonblocking algorithms

Проблемы блокировок �  Взаимоблокировки (Deadlocks) �  Инверсия приоритетов �  Надежность — вдруг владелец блокировки помрет?

�  Performance �  Параллелизма в критической секции нет! �  Владелец блокировки может быть вытеснен планировщиком

18

Page 19: Atomics, CAS and Nonblocking algorithms

Закон Амдала

�  α — часть общего объема вычислений, которую нельзя распараллелить

�  1-α — часть, которую можно распараллелить

�  p — количество потоков

19

Page 20: Atomics, CAS and Nonblocking algorithms

Закон Амдала

�  α — часть общего объема вычислений, которую нельзя распараллелить

�  1-α — часть, которую можно распараллелить

�  p — количество потоков

20

Page 21: Atomics, CAS and Nonblocking algorithms

Алгоритмы без блокировок �  Без препятствий (Obstruction-Free) — Поток совершает прогресс, если не встречает препятствий со стороны других потоков

�  Без блокировок (Lock-Free) — гарантируется системный прогресс хотя бы одного потока

�  Без ожидания (Wait-Free) — каждая операция выполняется за фиксированное число шагов, не зависящее от других потоков

21

Page 22: Atomics, CAS and Nonblocking algorithms

Консенсус �  Объект consensus с операцией decide(v):

�  consensus.decide(v) ≠ const �  Wait-free

�  N Потоков вызывают consensus.decide() �  i-ый поток вызывает consensus.decide(vi) �  Каждый поток вызывает не более 1 раза �  decide() возвращает одно из vi

�  decide() — протокол консенсуса 22

Page 23: Atomics, CAS and Nonblocking algorithms

Консенсусное число �  Мощность консенсуса — максимальное количество (N) потоков, для которых данный объект обеспечивает консенсус

�  Консенсусное число примитива синхронизации — максимальная мощность консенсуса, который можно построить на базе данного примитива и некоторого количества атомарных регистров �  То есть, существует реализация метода decide для N потоков, использующая данный примитив как строительный блок

23

Page 24: Atomics, CAS and Nonblocking algorithms

Консенсусное число �  Операции на регистрах — 1

�  Read-Modification-Write (RMW) — 2 �  Common2 Class — коммутируют друг с другом или перезаписывают друг друга

�  Универсальные операции — ∞ � Сравнение с обменом (CAS): Compare-And-Swap, Compare-And-Set

24

Page 25: Atomics, CAS and Nonblocking algorithms

Compare and Swap �  Compare-and-swap (CAS)

�  IA32, x64 �  SPARC

�  loadlinked + store-conditional (LL/SC) �  PowerPC �  ARM

25

Page 26: Atomics, CAS and Nonblocking algorithms

Семантика CAS

26

Page 27: Atomics, CAS and Nonblocking algorithms

Типичный паттерн применения 1. Прочитать значение A из переменной V

2. Взять какое-то новое значение B для V

3. Использовать CAS для атомарного изменения V из A в B до тех пор, пока другие потоки меняют значение V во время этого процесса

Атомарность Read-Modify-Write реализуется за счет постоянного мониторинга системы на предмет постороннего вмешательства

27

Page 28: Atomics, CAS and Nonblocking algorithms

Алгоритм 1: неблокирующий счетчик

28

Page 29: Atomics, CAS and Nonblocking algorithms

Fast path vs. long path �  Каждый блок кода может иметь, как минимум, два пути исполнения: короткий и длинный

�  Lock: contended vs. Uncontended

�  Uncontended Lock: �  ≥ 1 CAS �  Другая машинерия вокруг lock

29

Page 30: Atomics, CAS and Nonblocking algorithms

Недостатки CAS �  CAS заставляет потоки, которые его вызывают, работать в условиях соревнования (contention) �  Больше contention = больше бесполезных циклов

процессора, трата процессорного времени

�  Написание корректных и быстрых алгоритмов на CAS требует специальной подготовки

30

Page 31: Atomics, CAS and Nonblocking algorithms

Поддержка CAS в JVM �  В Java 5 появился JSR166

�  пакет java.util.concurrent �  пакет java.util.concurrent.atomic

�  На платформах, поддерживающих CAS, JIT-компилятор делает inline соответствующих машинных инструкций

�  Load Linked / Store Conditional

�  Интерпретатор использует Spin Lock

31

Page 32: Atomics, CAS and Nonblocking algorithms

Atomic variable classes �  Scalars

�  Field updaters

�  Arrays

�  Compound variables

�  Accumulators �  since Java 8

32

Page 33: Atomics, CAS and Nonblocking algorithms

Scalars �  AtomicBoolean

�  AtomicInteger

�  AtomicLong

�  AtomicReference

33

Page 34: Atomics, CAS and Nonblocking algorithms

AtomicInteger �  boolean compareAndSet(int expect, int update)

�  int addAndGet(int delta)

�  int getAndDecrement()

�  int getAndIncrement()

�  int incrementAndGet()

�  …

34

Page 35: Atomics, CAS and Nonblocking algorithms

Multivariable Invariant

35

Page 36: Atomics, CAS and Nonblocking algorithms

Multivariable Invariant

36

Page 37: Atomics, CAS and Nonblocking algorithms

Field Updaters �  AtomicIntegerFieldUpdater

�  Reflection-based updater for volatile int

�  AtomicLongFieldUpdater �  Reflection-based updater for volatile long

�  AtomicReferenceFieldUpdater

�  Reflection-based updater for object

37

Page 38: Atomics, CAS and Nonblocking algorithms

AtomicLongFieldUpdater �  long addAndGet(T obj, long delta)

�  boolean compareAndSet(T obj, long expect, long update)

�  long getAndAdd(T obj, long delta)

�  long incrementAndGet(T obj)

38

Page 39: Atomics, CAS and Nonblocking algorithms

AtomicLongFieldUpdater

39

Page 40: Atomics, CAS and Nonblocking algorithms

AtomicLongFieldUpdater

40

Page 41: Atomics, CAS and Nonblocking algorithms

Atomic Arrays �  AtomicIntegerArray

�  AtomicLongArray

�  AtomicReferenceArray

41

Page 42: Atomics, CAS and Nonblocking algorithms

AtomicLongArray �  long addAndGet(int i, long delta)

�  long getAndAdd(int i, long delta)

�  boolean compareAndSet(int i, long expect, long update)

�  long incrementAndGet(int i)

�  …

42

Page 43: Atomics, CAS and Nonblocking algorithms

Compound Variables �  AtomicMarkableReference

�  compareAndSet( V expectedReference, V newReference, boolean expectedMark, boolean newMark)

�  AtomicStampedReference �  boolean compareAndSet( V expectedReference, V newReference, int expectedStamp, int newStamp)

43

Page 44: Atomics, CAS and Nonblocking algorithms

Accumulators �  DoubleAccumulator

�  DoubleAdder

�  LongAccumulator

�  LongAdder

�  (Striped64)

44

Page 45: Atomics, CAS and Nonblocking algorithms

LongAccumulator �  void accumulate(long x)

�  long get()

�  long getThenReset()

�  Void reset()

45

Page 46: Atomics, CAS and Nonblocking algorithms

Неблокирующие алгоритмы �  Алгоритм называется неблокирующим, если отказ или остановка любого потока не может привести к отказу или остановке любого другого потока

�  Алгоритм называется свободным от блокировок, если на каждом шаге какой-то поток выполняет работу (make progress)

�  Аглоритмы на CAS могут быть одновременно неблокирующими и свободными от блокировок

46

Page 47: Atomics, CAS and Nonblocking algorithms

Неблокирующий стек

47

Page 48: Atomics, CAS and Nonblocking algorithms

Неблокирующий стек

48

Page 49: Atomics, CAS and Nonblocking algorithms

Неблокирующий стек — push

49

Page 50: Atomics, CAS and Nonblocking algorithms

Неблокирующий стек — pop

50

Page 51: Atomics, CAS and Nonblocking algorithms

Неблокирующая очередь �  Michael and Scott, 1996

�  Алгоритм неочевидный

�  Потоки помогают друг другу

51

Page 52: Atomics, CAS and Nonblocking algorithms

52

Page 53: Atomics, CAS and Nonblocking algorithms

Проблема ABA

53

Page 54: Atomics, CAS and Nonblocking algorithms

Литература �  java.util.concurrent.atomic — Java 8 doc

http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html

�  Brian Goetz,Java Concurrency in Practice http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

�  Herlihy, Shavit The Art of Multiprocessor Programming http://www.amazon.com/The-Multiprocessor-Programming-Revised-Reprint/dp/0123973376

�  Nitsan Wakart, Degrees of (Lock/Wait) Freedom http://psy-lob-saw.blogspot.com/2015/05/degrees-of-lockwait-freedom.html

�  OpenJDK sources 54

Page 55: Atomics, CAS and Nonblocking algorithms

Questions & Answers

55