Несколько процессов на нескольких процессорах чтения и записи одних и тех же данных
Сейчас я изучаю параллелизм и у меня есть некоторые сомнения.
Давайте возьмем пример на вики. http://en.wikipedia.org/wiki/Atomic_(computer_science)
Наивный, неатомарный способ читает значение, добавляет 1, а затем записывает обратно. Если одновременно запущены 2 процесса, шаги могут чередоваться друг с другом. Например, 1-й процесс читает и добавляет 1, но он приостанавливается. 2-й процесс читает, добавляет 1 и записывает обратно и прерывается. 1-й процесс возобновляется и записывает старое значение.
Я понимаю, как атомарное сравнение и обмен решает проблему. Он читает, добавляет 1 и использует для сравнения "сравнить и поменять местами" и повторить попытку в случае сбоя при сравнении и замене.
Тем не менее, я представляю себе сценарий, в котором у нас есть несколько ядер, выполняющих несколько потоков. Что если 1-й процесс и 2-й процесс выполняются в одно и то же время на разных ядрах? То есть Process1 на CPU1 выполняет чтение, добавление, сравнение и обмен в то же время, что Process2 на CPU2 выполняет чтение, добавление, сравнение и обмен. Я думаю, что сравнение и обмен тоже удастся.
Возможна ли такая ситуация? Если да, то как с этим бороться?
1 ответ
Сравнение и замена реализованы аппаратно; грубо говоря, процессор работает с шиной памяти, чтобы гарантировать, что ядро, выполняющее сравнение и обмен, имеет эксклюзивный доступ к общей памяти. Таким образом, буквально невозможно одновременно запустить два процесса: один из них первым получит (аппаратно-гарантированную) блокировку общей памяти.
Например, в Intel атомарное сравнение и замена реализовано в LOCK CMPXCHG. Префикс LOCK гарантирует, что:
В многопроцессорной среде сигнал LOCK# обеспечивает исключительное использование процессором любой совместно используемой памяти, пока сигнал утверждается.
( Руководство разработчика программного обеспечения Intel® 64 и IA-32, том 2 (2 A, 2B и 2C): Справочник по наборам инструкций, AZ, том 2 A, стр. 3-462).