Введение

Тип согласованности в программировании, основанный на синхронизации. Согласованность по выпуску (release consistency) — одна из моделей согласованности, основанных на синхронизации, используемых в параллельном программировании (например, в распределенной общей памяти, распределенных транзакциях и т.п.).

Введение

В современных параллельных вычислительных системах необходимо поддерживать согласованность памяти, чтобы избежать нежелательных последствий. Строгие модели согласованности, такие как последовательная согласованность, интуитивно понятны, но могут быть весьма ограничивающими с точки зрения производительности, поскольку они подавляют параллелизм на уровне инструкций, широко используемый в последовательном программировании. Для достижения более высокой производительности исследуются различные ослабленные модели, и модель release consistency является одной из наиболее агрессивных попыток ослабления.

Структура аппаратного обеспечения и усилия на уровне программы

Последовательная согласованность может быть достигнута простой аппаратной реализацией, в то время как согласованность по освобождению основана на наблюдении, что большинство параллельных программ должным образом синхронизированы. На уровне программирования синхронизация используется для явного определения порядка доступа к памяти в одном потоке, чтобы один доступ происходил после другого. При доступе к синхронизированной переменной аппаратное обеспечение гарантирует, что все локальные для процессора записи будут распространены на все остальные процессоры, и что все записи от других процессоров будут видны и собраны. В модели согласованности по освобождению действия входа и выхода из критической секции классифицируются как "приобретение" и "освобождение", и в обоих случаях в программу необходимо явно вставлять код, указывающий, когда выполнять эти операции.

Отключение замка

Выпуск блокировки можно рассматривать как тип синхронизации освобождения. Предположим, что операция цикла выполняется с использованием кода, показанного справа. Две нити намерены войти в критический раздел, прочитать самое последнее значение переменной , а затем выйти из критического раздела. Код показывает, что нить 0 сначала получает блокировку и входит в критическую секцию. Для корректного выполнения P1 должен прочитать самое последнее значение , записанное P0. В этом случае в критической секции может находиться только одна нить одновременно. Следовательно, сама синхронизация гарантирует, что успешное получение блокировки в P1 произойдет после освобождения блокировки P0. Кроме того, необходимо обеспечить порядок S2 > S3, поскольку P0 должен передать новое значение переменной в P1. По той же причине S5 должно произойти после S4. Корректность не нарушается, если обращения к памяти, следующие за освобождением блокировки, выполняются до завершения освобождения, или обращения к памяти, предшествующие получению блокировки, выполняются после ее получения. Однако код в критической секции не может быть выполнен до завершения получения блокировки, поскольку взаимное исключение может быть не гарантировано.

После ожидания

Синхронизация после ожидания — еще одна форма реализации согласованности выпуска. Как показано в коде справа, корректность может быть обеспечена, если постоперации выполняются только после завершения всех обращений к памяти, особенно записи в ‘a’. Кроме того, операции чтения не должны выполняться до завершения операции ожидания. S2 действует как синхронизация выпуска (release), а S3 — как синхронизация приобретения (acquire). Следовательно, S2 должно предотвращать выполнение последующих операций после него, а S3 — выполнение предшествующих операций до него. S2 не требуется предотвращать выполнение последующих операций до него, равно как и S3 не требуется предотвращать выполнение предшествующих операций после него.

Состоянность с невысоким выделением

Ленивая консистентность выпуска — это дальнейшая оптимизация консистентности выпуска. Она предполагает, что потоку, выполняющему операцию получения (acquire), не требуется видеть значения, записанные другими потоками, до тех пор, пока эта операция получения не будет завершена. Таким образом, все действия, связанные с когерентностью, могут быть отложены, а время распространения записи может быть скорректировано.

Пример

Рассмотрим сценарии, описанные на изображении справа. Этот пример демонстрирует, как выполняется распространение записи в кэш-когерентной системе, основанной на модели согласованности с освобождением (release consistency). Переменная datum полностью распространяется до распространения datumIsReady. Однако значение datum не требуется до тех пор, пока не произойдет доступ к синхронизации в P1, и его можно распространить вместе с datumIsReady, не повлияв на результат программы. На втором изображении показано, что происходит при использовании ленивой модели согласованности с освобождением (lazy release consistency). В этом сценарии все значения, записанные перед операцией освобождения, задерживаются и распространяются вместе с самой операцией освобождения. Следовательно, datum и datumIsReady распространяются вместе в точке освобождения. "TreadMarks" – это реальное применение ленивой модели согласованности с освобождением.

Улучшение производительности по сравнению с консистенцией выпуска

В некоторых случаях консистентность с "ленивым" освобождением может превосходить консистентность с освобождением. Если в системе небольшая пропускная способность между процессорами или она сильно страдает от высоких накладных расходов, связанных с частой передачей небольших блоков данных по сравнению с редкой передачей больших блоков данных, то LRC может существенно повысить производительность. Рассмотрим систему, использующую абстракцию общей памяти на уровне программного обеспечения, а не аппаратную реализацию. В такой системе распространение записи осуществляется на уровне страниц, что делает распространение целой страницы чрезвычайно затратным, если был изменен только один блок на этой странице. Поэтому распространение записи откладывается до момента достижения точки синхронизации освобождения, когда изменяется вся страница и происходит ее распространение.

Недостатки

LRC требует выполнения пакетного распространения записи в точке освобождения синхронизации. Распространение такого большого количества записей одновременно замедлит доступ при освобождении и последующий доступ при захвате. Следовательно, это вряд ли существенно улучшит производительность системы аппаратной когерентности кэша.

Слабое упорядочение (слабая последовательность)

Последовательная согласованность требует от программистов большего, чем слабое упорядочение. Они должны маркировать обращения к синхронизации как приобретения (acquire) или освобождения (release), а не просто как обращения к синхронизации. Подобно слабому упорядочению, последовательная согласованность позволяет компилятору свободно переупорядочивать загрузки и сохранения, за исключением того, что они не могут перемещаться вверх, за пределы синхронизации приобретения, и не могут перемещаться вниз, за пределы синхронизации освобождения. Однако гибкость и преимущество в производительности, предоставляемые последовательной согласованностью, достигаются ценой необходимости правильной идентификации обращений к синхронизации и их обозначения как приобретений и освобождений. В отличие от слабого упорядочения, обращения к синхронизации нельзя легко идентифицировать только по кодам операций инструкций. Таким образом, ответственность за правильную идентификацию обращений к синхронизации как приобретений и освобождений ложится на плечи программистов.

Процессорная консистенция

Для обеспечения консистентности процессоров, все процессы видят записи, сделанные каждым процессором, в том порядке, в котором они были инициированы. Записи с разных процессоров могут наблюдаться в разном порядке, за исключением случаев записи в одно и то же местоположение, которые будут видны во всех процессах в одном и том же порядке. По сравнению с консистентностью процессоров, release consistency (консистентность выпуска) является более слабой, поскольку не требует соблюдения порядка операций записи, как это требуется в консистентности процессоров. Она может противоречить интуиции программистов, так как предоставляет компилятору больше возможностей для оптимизации.