Рассмотрим следующий псевдокод:
expected = null;
if (variable == expected)
{
atomic_compare_exchange_strong(
&variable, expected, desired(), memory_order_acq_rel, memory_order_acq);
}
return variable;
Наблюдайте, нет ли семантики "приобретать", когда выполняется проверка variable == expected
.
Мне кажется, что desired
будет вызываться по крайней мере один раз в общей сложности и не более одного раза за поток.
Кроме того, если desired
никогда не возвращает null
, тогда этот код будет никогда возвращать null
.
Теперь у меня есть три вопроса:
-
Является ли это вышеизложенным обязательно? то есть, действительно ли мы можем иметь упорядоченные чтения общих переменных даже в отсутствие забора на каждом считывании?
-
Возможно ли реализовать это на С++? Если да, то как? Если нет, то почему?
(Надеюсь, с обоснованием, а не просто "потому что стандарт говорит так".) -
Если ответ на (2) да, то можно ли реализовать это в С++ без, требуя
variable == expected
выполнить атомное чтениеvariable
?
В принципе, моя цель состоит в том, чтобы понять, можно ли выполнить ленивую инициализацию общей переменной таким образом, чтобы производительность была идентичной производительности, не связанной с общей переменной, как только код был выполнен хотя бы один раз по каждому потоку
(Это скорее вопрос "язык-юрист". Поэтому подразумевается, что речь идет не о том, является ли это хорошей или полезной идеей, а скорее о том, можно ли технически это сделать правильно.)