53
XII международная конференция CEE-SECR / РАЗРАБОТКА ПО 28 - 29 октября, Москва Алексей Федоров Помоги ближнему, или Как потоки помогают друг другу Одноклассники

Помоги ближнему, или Как потоки помогают друг другу

Embed Size (px)

Citation preview

Page 1: Помоги ближнему, или Как потоки помогают друг другу

XIIмеждународнаяконференцияCEE-SECR/РАЗРАБОТКАПО28- 29 октября,Москва

АлексейФедоров

Помогиближнему,илиКакпотокипомогаютдругдругу

Одноклассники

Page 2: Помоги ближнему, или Как потоки помогают друг другу

Много интересных докладов в других залах

Page 3: Помоги ближнему, или Как потоки помогают друг другу
Page 4: Помоги ближнему, или Как потоки помогают друг другу

Pokemon илиBig Data?

https://pixelastic.github.io/pokemonorbigdata/

vs.

Page 5: Помоги ближнему, или Как потоки помогают друг другу
Page 6: Помоги ближнему, или Как потоки помогают друг другу
Page 7: Помоги ближнему, или Как потоки помогают друг другу
Page 8: Помоги ближнему, или Как потоки помогают друг другу
Page 9: Помоги ближнему, или Как потоки помогают друг другу
Page 10: Помоги ближнему, или Как потоки помогают друг другу
Page 11: Помоги ближнему, или Как потоки помогают друг другу

Это доклад не про Big Data!

Page 12: Помоги ближнему, или Как потоки помогают друг другу

Прочтоэтотдоклад� Программирование� Алгоритмы� Многопоточность

Page 13: Помоги ближнему, или Как потоки помогают друг другу

Много интересных докладов в других залах

Page 14: Помоги ближнему, или Как потоки помогают друг другу

Новичкам в области многопоточности

SorryПерейдите в другой зал

Прочтоэтотдоклад

Page 15: Помоги ближнему, или Как потоки помогают друг другу

Новичкам в области многопоточности

SorryПерейдите в другой зал

Новичкам в неблокирующей синхронизации

Короткое введение

Прочтоэтотдоклад

Page 16: Помоги ближнему, или Как потоки помогают друг другу

Новичкам в области многопоточности

SorryПерейдите в другой зал

Новичкам в неблокирующей синхронизации

Короткое введение

Продвинутым многопоточным программистам

Поговорим о фишечкахнеблокирующих алгоритмов

Прочтоэтотдоклад

Page 17: Помоги ближнему, или Как потоки помогают друг другу

Модели

Page 18: Помоги ближнему, или Как потоки помогают друг другу

Модели

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

� Операциинаатомарныхрегистрах:read,write

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

Модельспередачейсообщений

� Операции:send,onReceive

� Похожанато,какреальноработаетжелезо

Page 19: Помоги ближнему, или Как потоки помогают друг другу

Преимущества параллелизма

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

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

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

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

� Болееотзывчивые интерфейсыпользователя

� EventDispatchThread(EDT),async calls

Page 20: Помоги ближнему, или Как потоки помогают друг другу

� Взаимоблокировки (Deadlocks)

Проблемыблокировок

Page 21: Помоги ближнему, или Как потоки помогают друг другу

� Взаимоблокировки (Deadlocks)

� Инверсия приоритетов

Проблемыблокировок

Page 22: Помоги ближнему, или Как потоки помогают друг другу

� Взаимоблокировки (Deadlocks)

� Инверсия приоритетов

� Надежность — вдруг владелец блокировки помрет?

Проблемыблокировок

Page 23: Помоги ближнему, или Как потоки помогают друг другу

Проблемыблокировок� Взаимоблокировки (Deadlocks)

� Инверсия приоритетов

� Надежность — вдруг владелец блокировки помрет?

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

Page 24: Помоги ближнему, или Как потоки помогают друг другу

ЗаконАмдалаα часть общего объема вычислений,

которую нельзя распараллелить

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

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

Page 25: Помоги ближнему, или Как потоки помогают друг другу

Sp=𝟏

α#𝟏%α𝐩

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

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

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

ЗаконАмдала

Page 26: Помоги ближнему, или Как потоки помогают друг другу

Фундаментальныезаконыприроды� 19век— законыНьютона

Page 27: Помоги ближнему, или Как потоки помогают друг другу

Фундаментальныезаконыприроды� 19век— законыНьютона� 20век— законМура

� тактовыечастоты� числотранзисторов

Page 28: Помоги ближнему, или Как потоки помогают друг другу

Фундаментальныезаконыприроды� 19век— законыНьютона� 20век— законМура

� тактовыечастоты� числотранзисторов

� 21век— законАмдала

Page 29: Помоги ближнему, или Как потоки помогают друг другу

Фундаментальныезаконыприроды� 19век— законыНьютона� 20век— законМура

� тактовыечастоты� числотранзисторов

� 21век— законАмдала

Нарушение законавлечет засобойдисциплинарную,гражданско-правовую,административнуюилиуголовную ответственность

Page 30: Помоги ближнему, или Как потоки помогают друг другу

If-Modify-Write

volatile int value = 0;

if (value == 0) {value = 42;

}

Нет атомарности

Page 31: Помоги ближнему, или Как потоки помогают друг другу

CompareandSwap

int value = 0;

LOCKif (value == 0) {

value = 42;}

UNLOCK

Page 32: Помоги ближнему, или Как потоки помогают друг другу

Введемволшебнуюоперацию

int value = 0;

i.compareAndSet(0, 42);

Page 33: Помоги ближнему, или Как потоки помогают друг другу

CompareandSwap— HardwareSupport

compare-and-swapCAS

load-link / store-conditionalLL/SC

cmpxchg

ldrex/strex lwarx/stwcx

Page 34: Помоги ближнему, или Как потоки помогают друг другу

CASSemanticspublic 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);

}}

Page 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));

}

}

Page 36: Помоги ближнему, или Как потоки помогают друг другу

НедостаткиCAS

Contended CAS —> tons of useless CPU cycles

do {v = value.get();

} while (value.compareAndSet(v, v + 1));

Написание быстрых и корректных алгоритмов на CAS требует экспертизы

Page 37: Помоги ближнему, или Как потоки помогают друг другу
Page 38: Помоги ближнему, или Как потоки помогают друг другу
Page 39: Помоги ближнему, или Как потоки помогают друг другу

Michael and Scott, 1996https://www.research.ibm.com/people/m/michael/podc-1996.pdf

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

Неблокирующаяочередь

Page 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);

}

Page 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);

}

Page 42: Помоги ближнему, или Как потоки помогают друг другу

tailhead

dummy 1 2

Page 43: Помоги ближнему, или Как потоки помогают друг другу

tailhead

dummy 1 2 3

Page 44: Помоги ближнему, или Как потоки помогают друг другу

tailhead

dummy 1 2 3

Page 45: Помоги ближнему, или Как потоки помогают друг другу

public boolean put(E item) {Node<E> newNode = new Node<>(item, null);while (true) {

Node<E> currentTail = tail.get();Node<E> tailNext = currentTail.next.get();if (currentTail == tail.get()) {

if (tailNext != null) { // промежуточное состояниеобновляем tail

} else {// Консистентное состояние! Пытаемся добавить новую ноду

if (вставили_успешно) {пытаемся обновить tailreturn true;

}}

}}

}

Page 46: Помоги ближнему, или Как потоки помогают друг другу

public boolean put(E item) {Node<E> newNode = new Node<>(item, null);while (true) {

Node<E> currentTail = tail.get();Node<E> tailNext = currentTail.next.get();if (currentTail == tail.get()) {

if (tailNext != null) {tail.compareAndSet(currentTail, tailNext);

} else {if (currentTail.next.compareAndSet(null, newNode)) {

tail.compareAndSet(currentTail, newNode);return true;

}}

}}

}

Page 47: Помоги ближнему, или Как потоки помогают друг другу

Модификации

Page 48: Помоги ближнему, или Как потоки помогают друг другу

Ladan-Mozes, Shavit, 2004, 2008Идея:избавитьсяотвторогоCAS

OptimisticApproach

http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf

Page 49: Помоги ближнему, или Как потоки помогают друг другу

Hoffman, Shalev, Shavit, 2007

BasketsQueue

http://people.csail.mit.edu/shanir/publications/Baskets%20Queue.pdf

Page 50: Помоги ближнему, или Как потоки помогают друг другу

Материалы

Page 51: Помоги ближнему, или Как потоки помогают друг другу

51

Литература

Page 52: Помоги ближнему, или Как потоки помогают друг другу

52

Материалы

• Nitsan Wakart — http://psy-lob-saw.blogspot.com/• АлексейШипилёв — https://shipilev.net/• МаксимХижинский — https://habrahabr.ru/post/219201/

Page 53: Помоги ближнему, или Как потоки помогают друг другу

Вопросыиответы