Способствует ли порядок изменения отношениям "произойдет до"?

// Thread 1
// do A
x.store(1, std::memory_order_release); // operation1

// Thread 2
// do B
x.store(2, std::memory_order_release); // operation2

// Thread 3
x.load(std::memory_order_acquire); // operation3

Я понял, что если поток 3 читает значение, записанное потоком 1, операции освобождения и получения синхронизируются, и эффект A виден в теме 3
Но что, если дело в том, что:

  • порядок модификации для x это 1, 2
  • thread3 читает значение, записанное thread2, таким образом, 2 происходит до 3.

Есть ли связь между 1 и 3?
или, по сути, вносит ли порядок изменения в отношение " случается до"?

4 ответа

Решение

Нет, между операцией 1 и операцией 3 не происходит никаких отношений.

Из [atomics.order] / 2:

Атомная операция A, которая выполняет операцию освобождения атомарного объекта M, синхронизируется с атомарной операцией B, которая выполняет операцию получения для M и получает свое значение от любого побочного эффекта в последовательности выпуска, возглавляемой A.

... и, к сожалению, Операция 2 не находится в последовательности выпуска, возглавляемой Операцией 1 согласно [intro.races] / 5:

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

В результате мы не можем построить взаимосвязь между событиями до операции между операцией 1 и другими операциями, поэтому между операцией 1 и операцией 3 не существует связи между событиями.

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

В вашем примере вы показываете, что поток 1 и поток 2 работают с x одинаково. Следовательно, отношение между потоком 1 и потоком 3 должно быть точно таким же, как отношение между потоком 2 и потоком 3.

В вашем примере не показаны какие-либо строки кода, которые бы ограничивали порядок, в котором фактически выполняются три операции. Другими словами, просто взглянув на эти три утверждения, невозможно сказать, вернется ли операция загрузки 1, или же 2или какое-то предыдущее значение x,

"происходит раньше" означает, что если a произошло раньше, чем b, то эффекты видны b даже в другом потоке.

"случается раньше" не означает, что a гарантированно произойдет раньше b, это только означает, что если a получилось, b увидим это. это ваша работа как разработчика, чтобы убедиться, a происходит раньше b, если это важно для вашего приложения.

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

"приобретать" означает: любая запись, выполненная с семантикой релиза или более сильной, видна этому потоку, если читать атомарно. компилятору и процессору не разрешается путать код и выполнять атомарные операции чтения и записи в одном и том же потоке после этой операции получения.

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

почему некоторые операции чтения и записи могут быть испорчены компилятором и процессором? Оптимизации.

Другие вопросы по тегам