C++ lectures at MIPT (in Russian). Lecture 13. Atomicity, part 2

preview_player
Показать описание
Лекции в магистратуре МФТИ по C++ на русском языке.

В этой лекции мы продолжаем атомарность. На этот раз время остановиться на проектировании: API races, livelocks, ABA, всё остальное из этой серии. И мы успели начать модели памяти

Лектор: Константин Владимиров
Дата лекции: 10 марта 2020 года
Съёмка и звук: Дмитрий Рябцев

Errata:
* я как-то неубедительно рассказал про конкретные проблемы, вызываемые ABA. В начале следующей лекции исправлюсь
* 1:16:21 есть некая путаница с семантикой acquire/release, см. обсуждение в комментариях
Рекомендации по теме
Комментарии
Автор

Проблемы ABA можно избежать на ARM, если вместо стандартных атомиков использовать ассемблерные вставки с Load Exclusive/Store Exclusive. Дело в том, что store exclusive всегда завершается с ошибкой если область памяти перезаписали, даже если тем же самым значением.

victormustya
Автор

Прекрасная лекция. На ночь не смотрите, не совершайте моих ошибок, всё тлен...

DrUlrih
Автор

1:16:21 либо я неправильно понимаю, либо есть ошибка:
acquire - ВСЕ операции после fence будут выполнены только после всех чтений ДО fence. То есть, операции записи после fence могут попасть
release - ВСЕ операции до fence выполнятся ДО операций записи после fence. То есть, чтение может залезть до fence

astmix
Автор

40:40 слайд 67.
Кажется тут не только ABA problem, тут с формальной точки зрения UB, даже если другой поток просто удалил p, без новых аллокаций.
Два потока пытаются удалить голову. Первый поток успел сохранить указатель, а второй поток его уже удалил. Тогда при попытке CAS мы читаем из удаленной памяти p->next, что уже UB.

ivankorotkov
Автор

Было бы более честно chasing counter проверять с атомиками с memory_order_relaxed потому, что не совсем ясно в чем проблема или с не атомарным инкрементом или с переупорядочением.

xdtaux
Автор

1:11:50 Если a=1; b=2, то в первом случае c=2/3, а во втором c=1/2

TheDimchikb
Автор

В лекции на 16:48 (52 слайд) упомянули, что в if может войти несколько потоков и посчитать несколько раз checksum. Но более серьёзная вещь может случится, если войдут два потока, один не дойдёт до проверки, второй выставит cached = true, но не успеет посчитать checksum, после чего первый поток возобновится и увидит, что cached true, не зайдёт в if и вернёт 0 (как в случае с копированием)

viacheslavbarkov
Автор

Большое спасибо за интересное и глубокое изложение важного материала! У Вас на одном из слайдов написано: "Acquire (I+S) – "после значит после". Запрещает переупорядочивать записи вниз." и "Release (I+L) – "до значит до". Запрещает переупорядочивать чтения вверх." По-моему тут ошибка. Правильно должно быть: "Acquire (I+S) – "после значит после. Запрещает переупорядочивать чтения вверх." и "Release (I+L) – "до значит до". Запрещает переупорядочивать записи вниз." Или я что-то недопонимаю?

alexyoutuber
Автор

По поводу pop_front. Она обхявлена как T*, а написана как void. Если написать ее как T*, то разговоры о том, что имели ввиду удалить и удалили на самом деле приобретут совсем другой оборот.

TheDimchikb
Автор

Для data race есть ещё Google Thread Sanitizer:

victormustya