16. Новичкам в области
многопоточности
Sorry
Перейдите в другой зал
Новичкам в неблокирующей
синхронизации
Короткое введение
Продвинутым многопоточным
программистам
Поговорим о фишечках
неблокирующих алгоритмов
Про что этот доклад
23. Проблемы блокировок
— Взаимоблокировки (Deadlocks)
— Инверсия приоритетов
— Надежность — вдруг владелец блокировки помрет?
— Performance
— Параллелизма в критической секции нет!
— Владелец блокировки может быть вытеснен планировщиком
24. Закон Амдала
α часть общего объема вычислений,
которую нельзя распараллелить
1-α часть, которую можно распараллелить
p количество потоков
25. Sp=
𝟏
α#
𝟏%α
𝐩
α часть общего объема вычислений,
которую нельзя распараллелить
1-α часть, которую можно распараллелить
p количество потоков
Закон Амдала
29. Фундаментальные законы природы
— 19 век — законы Ньютона
— 20 век — закон Мура
— тактовые частоты
— число транзисторов
— 21 век — закон Амдала
Нарушение закона влечет за собой дисциплинарную,
гражданско-правовую, административную или
уголовную ответственность
34. CAS Semantics
public class PseudoCAS {
private long value;
public synchronized long get() { return value; }
public synchronized long compareAndSwap(long expected, long newV) {
long oldValue = value;
if (oldValue == expected) {
value = newV;
}
return oldValue;
}
public synchronized boolean compareAndSet(long expected, long newV){
return expected == compareAndSwap(expected, newV);
}
}
35. Пример 1. Многопоточный счетчик
public class CasLoopCounter implements Counter {
private AtomicLong value = new AtomicLong();
public long get() {
return value.get();
}
public void increment() {
long v;
do {
v = value.get();
} while (value.compareAndSet(v, v + 1));
}
}
36. Недостатки CAS
Contended CAS —> tons of useless CPU cycles
do {
v = value.get();
} while (value.compareAndSet(v, v + 1));
Написание быстрых и корректных алгоритмов на CAS
требует экспертизы
37.
38.
39. Michael and Scott, 1996
https://www.research.ibm.com/people/m/michael/podc-1996.pdf
Потоки помогают друг другу
Неблокирующая очередь
40. public class LinkedQueue<E> {
private static class Node<E> {
final E item;
final AtomicReference<Node<E>> next;
public Node(E item, AtomicReference<Node<E>> next) {
this.item = item;
this.next = next;
}
}
private final Node<E> dummy = new Node<>(null, null);
private final AtomicReference<Node<E>> head = new AtomicReference<>(dummy);
private final AtomicReference<Node<E>> tail = new AtomicReference<>(dummy);
}
41. public class LinkedQueue<E> {
private static class Node<E> {
final E item;
final AtomicReference<Node<E>> next;
public Node(E item, AtomicReference<Node<E>> next) {
this.item = item;
this.next = next;
}
}
private final Node<E> dummy = new Node<>(null, null);
private final AtomicReference<Node<E>> head = new AtomicReference<>(dummy);
private final AtomicReference<Node<E>> tail = new AtomicReference<>(dummy);
}
48. Ladan-Mozes, Shavit, 2004, 2008
Идея: избавиться от второго CAS
Optimistic Approach
http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf