В информатике и инженерии, транзакционной памяти попытки для упрощения параллельного программирования, позволяя группе инструкций загрузки и сохранения выполняться атомарным способом. Это механизм управления параллелизмом, аналогичный транзакциям базы данных для управления доступом к совместно используемой памяти в параллельных вычислениях. Системы транзакционной памяти предоставляют абстракцию высокого уровня как альтернативу низкоуровневой синхронизации потоков. Эта абстракция позволяет координировать параллельные операции чтения и записи общих данных в параллельных системах.
В параллельном программировании требуется синхронизация, когда параллельные потоки пытаются получить доступ к общий ресурс. Конструкции низкоуровневой синхронизации потоков, такие как блокировки, пессимистичны и запрещают потокам, находящимся за пределами критического раздела , вносить какие-либо изменения. Процесс наложения и снятия блокировок часто функционирует как дополнительные накладные расходы в рабочих нагрузках с небольшим конфликтом между потоками. Транзакционная память обеспечивает оптимистичное управление параллелизмом, позволяя потокам работать параллельно с минимальным вмешательством. Целью систем транзакционной памяти является прозрачная поддержка областей кода, помеченных как транзакции, путем обеспечения атомарности, согласованности и изоляции.
Транзакция - это набор операций, которые могут выполнять и фиксировать изменения до тех пор, пока нет конфликта. При обнаружении конфликта транзакция вернется в исходное состояние (до каких-либо изменений) и будет выполняться повторно, пока все конфликты не будут устранены. До успешной фиксации результат любой операции внутри транзакции является чисто умозрительным. В отличие от синхронизации на основе блокировок, когда операции сериализуются для предотвращения повреждения данных, транзакции допускают дополнительный параллелизм, пока несколько операций пытаются изменить общий ресурс. Поскольку программист не несет ответственности за явную идентификацию блокировок или порядок их получения, программы, использующие транзакционную память, не могут создать взаимоблокировку.
При наличии этих конструкций транзакционная память обеспечивает абстракцию программирования высокого уровня, позволяя программисты заключают свои методы в транзакционные блоки. Правильные реализации гарантируют, что данные не могут быть разделены между потоками без прохождения транзакции, и дают результат сериализуемый. Например, код может быть записан как:
def transfer_money (from_account, to_account, amount): "" "Перевести деньги с одного счета на другой." "" With transaction (): from_account - = сумма to_account + = amount
В коде блоку, определенному как «транзакция», гарантируется атомарность, согласованность и изоляция с помощью базовой реализации транзакционной памяти, и он прозрачен для программиста. Переменные внутри транзакции защищены от внешних конфликтов, гарантируя, что либо будет переведена правильная сумма, либо не будет предпринято никаких действий. Обратите внимание, что ошибки, связанные с параллелизмом, все еще возможны в программах, которые используют большое количество транзакций, особенно в программных реализациях, где библиотека, предоставляемая языком, не может обеспечить правильное использование. Ошибки, возникшие в результате транзакций, часто бывает трудно отладить, поскольку точки останова не могут быть размещены внутри транзакции.
Транзакционная память ограничена тем, что требует абстракции совместно используемой памяти. Хотя программы транзакционной памяти не могут вызвать тупик, программы все равно могут страдать от динамической блокировки или нехватки ресурсов . Например, более длинные транзакции могут неоднократно возвращаться в ответ на несколько меньших транзакций, тратя время и энергию.
Программная транзакционная память обеспечивает семантику транзакционной памяти в программной библиотеке времени выполнения или языке программирования и требует минимальной аппаратной поддержки (обычно атомарная операция сравнения и замены или эквивалент). Обратной стороной является то, что программные реализации обычно приводят к снижению производительности по сравнению с аппаратными решениями. Аппаратное ускорение может снизить некоторые накладные расходы, связанные с программной транзакционной памятью.
Из-за более ограниченного характера аппаратной транзакционной памяти (в текущих реализациях) программное обеспечение, использующее ее, может потребовать довольно обширной настройки, чтобы в полной мере использовать ее. Например, динамический распределитель памяти может иметь значительное влияние на производительность, и аналогичным образом заполнение структуры может влиять на производительность (из-за выравнивания кеша и ложных проблем совместного использования); в контексте виртуальной машины различные фоновые потоки могут вызывать неожиданные прерывания транзакции.
Одной из самых ранних реализаций транзакционной памяти был буфер стробированного хранилища, использовавшийся в Transmeta процессоры Crusoe и Efficeon. Однако это использовалось только для облегчения умозрительной оптимизации для двоичной трансляции, а не для любой формы умозрительной многопоточности или для непосредственного раскрытия ее программистам. Azul Systems также внедрила аппаратную транзакционную память для ускорения своих устройств Java, но это также было скрыто от посторонних.
Sun Microsystems реализовала аппаратную транзакционную память и ограниченную форму спекулятивной многопоточности в ее высокопроизводительных устройствах. конец Рок-процессор. Эта реализация доказала, что ее можно использовать для исключения блокировок и более сложных гибридных систем транзакционной памяти, в которых транзакции обрабатываются с помощью комбинации аппаратного и программного обеспечения. Процессор Rock был закрыт в 2009 году, как раз перед приобретением Oracle ; хотя настоящие продукты никогда не были выпущены, исследователям был доступен ряд прототипов систем.
В 2009 году AMD предложила Advanced Synchronization Facility (ASF), набор расширений x86, которые предоставляют очень ограниченную форму поддержки аппаратной памяти транзакций. Целью было предоставить аппаратные примитивы, которые можно было бы использовать для синхронизации более высокого уровня, такие как программная транзакционная память или алгоритмы без блокировки. Однако AMD не объявила, будет ли ASF использоваться в продуктах, и если да, то в какие сроки.
Недавно IBM объявила в 2011 году, что Blue Gene / Q имел аппаратную поддержку как для транзакционной памяти, так и для спекулятивной многопоточности. Транзакционная память может быть настроена в двух режимах; Первый - это неупорядоченный и одноверсионный режим, в котором запись из одной транзакции вызывает конфликт с любыми транзакциями, читающими тот же адрес памяти. Второй режим предназначен для спекулятивной многопоточности, обеспечивая упорядоченную многоверсионную транзакционную память. Спекулятивные потоки могут иметь разные версии одного и того же адреса памяти, а аппаратная реализация отслеживает возраст каждого потока. Младшие потоки могут получать доступ к данным из старых потоков (но не наоборот), и запись по одному и тому же адресу основана на порядке потоков. В некоторых случаях зависимости между потоками могут привести к прерыванию работы младших версий.
Intel Transactional Synchronization Extensions (TSX) доступен в некоторых процессорах Skylake. Ранее он был реализован в процессорах Haswell и Broadwell, но реализации оба раза оказывались дефектными и поддержка TSX была отключена. Спецификация TSX описывает API транзакционной памяти для использования разработчиками программного обеспечения, но не раскрывает детали технической реализации. Архитектура ARM имеет аналогичное расширение.
Начиная с GCC 4.7, экспериментальная библиотека для транзакций доступна память, в которой используется гибридная реализация. Вариант Python PyPy также вводит в язык транзакционную память.