Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Юрий Кербицков «Свобода от блокировок или lock-...

Юрий Кербицков «Свобода от блокировок или lock-free многопоточность»

Во время разработки многопоточного кода практически всегда встаёт проблема параллельного доступа к ресурсам. Благо у нас есть необходимый инструментарий для решения этой проблемы. Самым простым способом решения проблемы параллельного доступа к ресурсам являются блокировки. В большинстве разрабатываемых приложений этого достаточно. Но когда на первый план выходит производительность и быстрый отклик, то блокировки могут послужить одним из узких мест. Чтобы повысить производительность и избежать накладных расходов блокировок существуют различные подходы и алгоритмы. Самыми идеальными являются wait-free алгоритмы, но, к сожалению, на практике, ситуации в которых мы можем их использовать, встречаются довольно редко. В этом докладе рассмотрим основные алгоритмы lock-free многопоточности, поговорим о некоторых оптимизациях компилятора, а также сравним производительность lock-free и не lock-free многопоточного кода.

DotNetRu

March 15, 2018
Tweet

More Decks by DotNetRu

Other Decks in Programming

Transcript

  1. НЕБЛОКИРУЮЩАЯ СИНХРОНИЗАЦИЯ Подход в параллельном программировании на симметрично-многопроцессорных системах, в

    котором принят отказ от традиционных примитивов блокировки, таких, как семафоры, мьютексы и события.
  2. ЧТО НУЖНО ПОМНИТЬ ПРО MONITOR  Реализует паттерн «условная переменная»

    (Conditional Variable)  Использует мьютекс  Большую часть времени выполняется в пользовательском режиме  Переходит в режим ядра при длительном времени ожидания
  3. ПРОЦЕССОР З – запись данных в память Ч – чтение

    данных из памяти В – выполнение инструкции
  4. ПРОЦЕССОР З – запись данных в память Ч – чтение

    данных из памяти В – выполнение инструкции Цикл 0 1 2 3 4 Инструкция 1 Ч В З Инструкция 2 Ч В З Инструкция 3 Ч В З Скалярный
  5. ПРОЦЕССОР З – запись данных в память Ч – чтение

    данных из памяти В – выполнение инструкции Цикл 0 1 2 3 4 Инструкция 1 Ч В З Инструкция 2 Ч В З Инструкция 3 Ч В З Инструкция 4 Ч В З Инструкция 5 Ч В З Инструкция 6 Ч В З Супер скалярный
  6. ЧТО В ИТОГЕ?  Последовательность следования инструкций такая, какой мы

    написали в коде  Реальная последовательность выполнения инструкций  Возможные последовательности выполнения инструкций  Все платформы имеют модель памяти, которая четко описывает допустимые перестановки
  7. АТОМАРНОСТЬ  Операция записи/чтения 32-х битных и менее значений всегда

    атомарна  Операция записи/чтения 64-х битных значений атомарна только в 64-х битной ОС
  8. АТОМАРНОСТЬ  Операция записи/чтения 32-х битных и менее значений всегда

    атомарна  Операция записи/чтения 64-х битных значений атомарна только в 64-х битной ОС Атомарные типы данных ▪ bool, char, byte, sbyte, short, ushort, uint, int, float ▪ Ссылочные типы ▪ Перечисления, чей базовый тип: byte, sbyte, short, ushort, int, uint
  9. COMPARE AND EXCHANGE (CAS)  Прочитать значение, сравнить в компарандом.

    Если равны, то записать новое значение  CMPXCHG инструкция
  10. МОДЕЛИ ПАМЯТИ  Слабая – разрешает переставлять все операции чтения/записи

     Сильная – не разрешает никаких перестановок. Код, который выполняется = исходному коду, который написан разработчиком
  11. МОДЕЛИ ПАМЯТИ X86 AMD64 ARMv7 Чтение после Чтения - -

    + Чтение после Записи - - + Запись после Записи - - + Запись после Чтения + + +
  12. БАРЬЕРЫ ПАМЯТИ. ПРОЦЕССОР  Полный барьер – никакие перестановки операций

    чтения/записи не могут быть сделаны через этот барьер (MFENCE инструкция)  Барьер операции записи (SFENCE инструкция) – запрещает перестановки операций записи через себя  Барьер операции чтения (LFENCE) – запрещает перестановки операций чтения через себя
  13. БАРЬЕРЫ ПАМЯТИ. КОМПИЛЯТОР  Acquire – запрещает операции чтения/записи переносить

    и ставить перед собой  Release – запрещает операции чтения/записи переносить и ставить после себя ACQUIRE // код до // код после RELEASE // код до // код после
  14. ДОСТОИНСТВА  Производительность НЕДОСТАТКИ  Требуется высокая квалификация и обширные

    знания для корректной реализации алгоритмов  При длительных периодах ожидания увеличивается утилизация процессора и возрастает нагрузка на кэш для поддержания когерентности  Код становится более запутанным и сложным