6. Модели
— Модель с разделяемой памятью
— Регистры
— Операции: read, write
— Удобно программировать, все привыкли
— Модель с передачей сообщений
— Послать сообщение
— Похожа на то, как реально работает железо
6
8. Виды параллелизма
— На уровне операционной системы
— На уровне одной программы / процесса
8
9. Параллелизм — ОС
— Слушать музыку и переписываться
в фейсбуке в Одноклассниках
— При зависании одной программы другие
продолжают работать
— и т.п.
9
10. Преимущества параллелизма
— Использование нескольких ядер/процессоров
— Да и на 1 ядре тоже! (async I/O)
— Простота моделирования
— Абстракция: фреймворк забирает сложность
— Упрощенная обработка асинхронных событий
— Более отзывчивые интерфейсы пользователя
— Event Dispatch Thread (EDT), async calls
10
11. Параллелизм на уровне
отдельно взятой программы
— Эффективное использование ресурсов
— Удобство, простота написания кода
— Справедливость
— Обработка запросов пользователей на
серверах соцсети с одинаковым приоритетом
— Читатели и писатели
— Fairness (честность)
11
18. Проблемы блокировок
— Взаимоблокировки (Deadlocks)
— Инверсия приоритетов
— Надежность — вдруг владелец блокировки
помрет?
— Performance
— Параллелизма в критической секции нет!
— Владелец блокировки может быть вытеснен
планировщиком
18
19. Закон Амдала
— α — часть общего объема вычислений,
которую нельзя распараллелить
— 1-α — часть, которую можно распараллелить
— p — количество потоков
19
20. Закон Амдала
— α — часть общего объема вычислений,
которую нельзя распараллелить
— 1-α — часть, которую можно распараллелить
— p — количество потоков
20
21. Алгоритмы без блокировок
— Без препятствий (Obstruction-Free) —
Поток совершает прогресс, если не встречает
препятствий со стороны других потоков
— Без блокировок (Lock-Free) — гарантируется
системный прогресс хотя бы одного потока
— Без ожидания (Wait-Free) — каждая операция
выполняется за фиксированное число шагов,
не зависящее от других потоков
21
22. Консенсус
— Объект consensus с операцией decide(v):
— consensus.decide(v) ≠ const
— Wait-free
— N Потоков вызывают consensus.decide()
— i-ый поток вызывает consensus.decide(vi)
— Каждый поток вызывает не более 1 раза
— decide() возвращает одно из vi
— decide() — протокол консенсуса
22
23. Консенсусное число
— Мощность консенсуса — максимальное
количество (N) потоков, для которых данный
объект обеспечивает консенсус
— Консенсусное число примитива синхронизации
— максимальная мощность консенсуса, который
можно построить на базе данного примитива и
некоторого количества атомарных регистров
— То есть, существует реализация метода
decide для N потоков, использующая данный
примитив как строительный блок
23
24. Консенсусное число
— Операции на регистрах — 1
— Read-Modification-Write (RMW) — 2
— Common2 Class — коммутируют друг с
другом или перезаписывают друг друга
— Универсальные операции — ∞
— Сравнение с обменом (CAS):
Compare-And-Swap, Compare-And-Set
24
27. Типичный паттерн применения
1. Прочитать значение A из переменной V
2. Взять какое-то новое значение B для V
3. Использовать CAS для атомарного изменения V
из A в B до тех пор, пока другие потоки
меняют значение V во время этого процесса
Атомарность Read-Modify-Write реализуется за
счет постоянного мониторинга системы на
предмет постороннего вмешательства
27
29. Fast path vs. long path
— Каждый блок кода может иметь, как минимум,
два пути исполнения: короткий и длинный
— Lock: contended vs. Uncontended
— Uncontended Lock:
— ≥ 1 CAS
— Другая машинерия вокруг lock
29
30. Недостатки CAS
— CAS заставляет потоки, которые его вызывают,
работать в условиях соревнования
(contention)
— Больше contention = больше бесполезных циклов
процессора, трата процессорного времени
— Написание корректных и быстрых алгоритмов на
CAS требует специальной подготовки
30
31. Поддержка CAS в JVM
— В Java 5 появился JSR166
— пакет java.util.concurrent
— пакет java.util.concurrent.atomic
— На платформах, поддерживающих CAS, JIT-
компилятор делает inline соответствующих
машинных инструкций
— Load Linked / Store Conditional
— Интерпретатор использует Spin Lock
31
34. AtomicInteger
— boolean compareAndSet(int expect, int update)
— int addAndGet(int delta)
— int getAndDecrement()
— int getAndIncrement()
— int incrementAndGet()
— …
34
37. Field Updaters
— AtomicIntegerFieldUpdater
— Reflection-based updater for volatile int
— AtomicLongFieldUpdater
— Reflection-based updater for volatile long
— AtomicReferenceFieldUpdater
— Reflection-based updater for object
37
38. 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
42. 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
43. Compound Variables
— AtomicMarkableReference
— compareAndSet(
V expectedReference, V newReference,
boolean expectedMark, boolean newMark)
— AtomicStampedReference
— boolean compareAndSet(
V expectedReference, V newReference,
int expectedStamp, int newStamp)
43
46. Неблокирующие алгоритмы
— Алгоритм называется неблокирующим, если
отказ или остановка любого потока не может
привести к отказу или остановке любого
другого потока
— Алгоритм называется свободным от блокировок,
если на каждом шаге какой-то поток выполняет
работу (make progress)
— Аглоритмы на CAS могут быть одновременно
неблокирующими и свободными от блокировок
46
54. Литература
— 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