Loading AI tools
Из Википедии, свободной энциклопедии
В компьютерных технологиях, программная транзакционная память (англ. software transactional memory, SТМ) представляет собой механизм управления параллелизмом, аналогичный механизму транзакций баз данных для управления доступом к совместно используемой памяти в параллельных вычислениях. Это альтернатива для синхронизации на основе блокировки. Транзакция в этом контексте является частью кода, который выполняет считывание и запись в разделяемую (совместно используемую) память. Считывание и запись логически происходит в единичный момент времени, а промежуточные состояния невидимы для других (результативных) транзакций. Идея обеспечения транзакций аппаратной поддержкой зародилась в 1986 году в работе и патенте Тома Найта.[1] Идея получила публичное освещение благодаря Морису Херлихи и Элиоту Моссу[англ.].[2] В 1995 году Нир Шавит и Дэн Тойту дополнили эту идею до программной транзакционной памяти (SТМ). STM по-прежнему находится в центре интенсивных исследований; возрастает её поддержка для практических реализаций.
Для улучшения этой статьи желательно:
|
В отличие от методов блокировки, используемых в большинстве современных многопоточных приложений, STM очень оптимистична: поток завершает изменения разделяемой памяти без учёта того, что делают другие потоки, и регистрирует любое считывание и запись в лог. Вместо того, чтобы использовать записывающее устройство для проверки, не оказывает ли он отрицательного влияния на другие действующие операции, ответственность передаётся считывающему устройству, которое после завершения полной транзакции проверяет, не произвели ли другие потоки параллельно изменения в памяти, к которой был получен доступ в прошлом. Эта последняя операция, в которой проверяются изменения транзакций и которая, если проверка успешна, остаётся неизменной, называется фиксацией. Транзакция может прекратиться в любое время, в результате чего все последние изменения будут отменены. Если транзакция не может быть совершена из-за конфликтов изменений, она прерывается и повторно выполняется сначала до тех пор, пока результативно не завершится.
Преимущество такого оптимистического подхода возрастает благодаря параллелизму: ни одному потоку не нужно ожидать получения доступа к ресурсу, и разные потоки могут одновременно и безопасно модифицировать непересекающиеся части структуры данных, которые защищались бы одним локом.
Однако на практике SТМ-системы проигрывают в производительности мелкомодульным системам, основанным на блокировках, на небольшом количестве процессоров (от 1 до 4 в зависимости от приложения). Это связано в первую очередь с накладными расходами на поддержку лога и с затрачиваемым временем на совершение транзакций. Но даже в этом случае производительность отличается не более, чем в 2 раза.[3] Сторонники STM считают, что такие потери оправданы концептуальными преимуществами SТМ.
Теоретически, временная и пространственная сложности выполнения n параллельных транзакций в худшем случае - O(n). Фактические затраты зависят от реализации (можно отменить транзакцию на ранней стадии, чтобы избежать накладных расходов), но всегда будут случаи, хоть и редкие, когда lock-алгоритмы будут иметь лучшую временную сложность, чем программная транзакционная память.
В дополнение к преимуществам производительности, STM значительно упрощает концептуальное понимание многопоточных программ и помогает их удобному сопровождению, слаженно работая с существующими высокоуровневыми абстракциями, такими как объекты и модули.
Lock-программирование содержит ряд известных проблем, которые часто возникают на практике:
Напротив, концепция транзакционной памяти гораздо проще, потому что каждая транзакция может рассматриваться по отдельности, как однопоточное вычисление. Тупики или предотвращаются полностью, или разрешаются внешней программой управления транзакций; программисту вряд ли нужно беспокоиться об этом. Инверсия приоритетов по-прежнему может быть проблемой, но высокоприоритетные транзакции могут прервать конфликтующие низкоприоритетные операции, которые ещё не были совершены.
С другой стороны, необходимость прерывания неудавшихся транзакций также накладывает ограничения на их поведение: они не могут выполнять любые операции, которые не могут быть отменены, в том числе большинство вводов-выводов. Такие ограничения, как правило, на практике преодолеваются путём создания буферов, которые ставят в очередь необратимые операции и выполняют их спустя некоторое время вне какой-либо транзакции. В языке Хаскель это ограничение приводится в исполнение системой типов во время компиляции.
В 2005 году Тим Харрис, Саймон Марлоу, Саймон Пейтон-Джонс и Морис Херлихи описали STM-систему, созданную на Хаскеле, реализующем параллелизм. Эта система позволяет произвольным атомарным операциям компоноваться в более крупные атомарные операции — полезная концепция, невозможная при lock-программировании. По словам авторов:
«Пожалуй, наиболее фундаментальный недостаток в том, что lock-программы не могут компоновать: корректные фрагменты могут не сработать, будучи скомпонованными. Рассмотрим, например, хеш-таблицу с потокобезопасными операциями вставки и удаления. Теперь предположим, что мы хотим удалить один элемент из таблицы t1 и вставить его в таблицу t2, но промежуточное состояние (в котором ни одна таблица не содержит этот элемент)не должно быть видимым для других потоков. Пока конструктор хеш-таблицы не определит данную необходимость, просто не существует способа удовлетворить этому требованию. В общем, каждая корректная операция (вставки, удаления) не могут быть скомпонована в более крупные корректные операции»
— (Тим Харрис и др.,"Компонуемая операция обращения к памяти", раздел 2. История вопроса,с.2)
С STM эта проблема решается просто: простое объединение двух операций в одной транзакции превращает компонуемую операцию в атомарную. Единственным камнем преткновения является то, что для абонента, который не знает деталей реализации методов компоновки, неясно когда они должны попытаться повторно выполнить транзакцию, если она не производится. В ответ на это, авторы предложили команду повторной попытки, которая использует журнал транзакций (log-файл), генерируемый неудавшейся транзакцией для определения считываемого ею участка памяти. Тогда она снова автоматически запускает данную транзакцию, когда один из этих участков памяти меняется. Это основывается на логике, что транзакция не будет вести себя иначе, пока хотя бы одно такое значение не изменилось.
Авторы также предложили механизм построения альтернатив (функция илиИначе — orElse). Он запускает одну транзакцию и, если транзакция делает повторную попытку, запускает вторую. Если то же происходит и со второй, механизм запускает их обе снова, пока не произойдут существенные изменения. Данная функция, сопоставимая с функцией сетевого стандарта POSIX select(), позволяет вызывающему ожидать любое из ряда событий одновременно. Она также упрощает программирование интерфейсов, например, путём предоставления простого механизма конвертации между блокирующими и неблокирующими операциями.
Концептуальная простота SТМ-систем позволяет программисту легко работать с ними, используя относительно простой синтаксис языка. В своей книге «Вспомогательный язык для лёгких транзакций» Тим Харрис и Кейр Фрейзер предложили идею использования классической условной критической области (CCR) для представления транзакций. В своей простейшей форме это всего лишь «атомарный блок», участок кода, который последовательно выполняется в единичный момент времени:
// Атомарная вставка узла в двусвязный список atomic { newNode->prev = node; newNode->next = node->next; node->next->prev = newNode; node->next = newNode; }
По достижении конца блока транзакция совершается, если это возможно, иначе прекращается и повторяется. Условные критические области также допускают условие сохранения, позволяющее транзакции ожидать выполнения, пока действует её задание.
atomic (queueSize > 0) { remove item from queue and use it }
Если условие не выполняется, программа управления (менеджер) транзакций будет ждать, пока не совершится другая, которая повлияет на условие прежде, чем повторит попытку. Такая свободная связь между производителями и потребителями совершенствует модульный принцип по сравнению с чётким сигнализированием между потоками. Книга «Компонуемая операция обращения к памяти» пошла дальше со своей командой повторной попытки (см. выше), которая может в любое время прервать транзакцию и ожидать, пока не произойдёт какое-либо изменение значения, ранее считанного данной операцией, перед повторением попытки. Пример:
atomic { if (queueSize > 0) { remove item from queue and use it } else { retry } }
Эта способность динамического повторения в конце транзакции упрощает модель программирования и открывает новые возможности.
Одной из проблем является поведение исключений, когда они распространяются за пределы транзакций. В труде " Компонуемая операция обращения к памяти " авторы решили, что это должно прервать транзакцию, так как исключения обычно указывают на неожиданные ошибки в языке Хаскель (с параллелизмом), но что это исключение может хранить предоставленную информацию и считывать её во время транзакции в целях диагностики. Они подчёркивают, что разумны также и другие проектные решения при других параметрах.
SТМ может быть реализована как алгоритм без блокировок и с блокировками. Есть два типа блокировки.
Схема совершения транзакции, названная «Транзакционная блокировка-2» и реализованная Дайсом, Шалевым и Шавитом, использует глобальное время. Каждая транзакция начинается с чтения текущего значения времени и хранит его для чтения. Затем при каждом чтении и записи версия определённой области памяти сравнивается с версией для чтения, и, если оно больше, то транзакция отменяется. Это гарантирует, что код выполнится на соответствующей копии памяти. Во время совершения все области чтения заблокированы, и значения данной версии всех областей памяти для записи и чтения повторно проверяются. Наконец, глобальное время увеличивается, новые значения записи из журнала записываются обратно в память с указанием новой версии времени.
Всё более популярным методом управления транзакционными конфликтами в транзакционной памяти, особенно в SТМ, является порядок совершения[англ.] (СО). Он используется для достижения упорядочиваемости безблокировочно (то есть без блокировки при конфликте операций и только с блокировкой при совершении транзакции) при помощи изменения порядка совершения транзакций (например, Рамадан и соавторы, 2009, и Жанг и соавторы, 2006). Упорядочиваемость является основой для корректного состояния транзакционной памяти (при выполнении параллельных транзакций). Уже были опубликованы десятки статей и патентов об STM с применением « порядка совершения».
«Жанг и соавторы, 2006» — патент США, несущий название «Программное обеспечение порядка совершения транзакций и управление конфликтами» (который ссылается на патент США 5701480 о порядке совершения). Приведём выдержки:
"Разрабатываются различные технологии и методы для применения порядка совершения в системе программной транзакционной памяти. Система программной транзакционной памяти снабжена функцией, чтобы предопределённый порядок совершения был применим для множества операций. Предопределённый порядок совершения используется во время выполнения, чтобы установить порядок, в котором совершать транзакции в системе программной транзакционной памяти. Процесс управления конфликтами вызывается, когда происходит конфликт между первой и второй транзакциями. Предопределённый порядок совершения используется в процессе управления конфликтами, чтобы определить, какая из транзакций должна выиграть конфликт и получить разрешение на продолжение".
С порядком совершения желаемое свойство упорядоченности осуществляется путём совершения транзакций только в хронологическом порядке, совместимом с порядком по приоритету (как определено хронологическим порядком операций в конфликтах)
Список примеров в этой статье не основывается на авторитетных источниках, посвящённых непосредственно предмету статьи. |
SRTM было реализовано (разного качества и стабильности) на разных языках программирования. Таких, как:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.