Учитывая следующий код:
std::atomic<int> counter;
/* otherStuff 1 */
counter.fetch_add(1, std::memory_order_relaxed);
/* otherStuff 2 */
Есть ли в x86-64 инструкция (скажем, менее 5-летней архитектуры), которая позволила бы переупорядочить otherStuff 1 и 2 через fetch_add
или это будет всегда сериализация?
РЕДАКТИРОВАТЬ:
Похоже, это суммируется lock add
барьер памяти на x86? »и, похоже, это не так, хотя я не уверен, где найти ссылку на это.
Сначала давайте посмотрим, что разрешено делать компилятору при использовании std::memory_order_relaxed
,
Если нет зависимости между otherStuff 1/2
и атомная операция, это, конечно, может изменить порядок заявлений. Например:
g = 3;
a.fetch_add(1, memory_order_relaxed);
g += 12;
clang ++ генерирует следующую сборку:
lock addl $0x1,0x2009f5(%rip) # 0x601040 <a>
movl $0xf,0x2009e7(%rip) # 0x60103c <g>
Здесь Clang позволил себе изменить порядок g = 3
с атомным fetch_add
операция, которая является законным преобразованием.
Когда используешь std::memory_order_seq_cst
, вывод компилятора становится:
movl $0x3,0x2009f2(%rip) # 0x60103c <g>
lock addl $0x1,0x2009eb(%rip) # 0x601040 <a>
addl $0xc,0x2009e0(%rip) # 0x60103c <g>
Переупорядочение операторов не происходит, потому что компилятору не разрешено это делать.
Последовательное последовательное упорядочение в операции чтения-изменения-записи (RMW) является одновременно выпуском и операцией получения, и, как таковое, не допускается (видимое) переупорядочение операторов как на уровне компилятора, так и на уровне ЦП.
Ваш вопрос: X86-64
, std::atomic::fetch_add
с использованием упорядоченного упорядочения является операцией сериализации.
Ответ: да, если вы не учитываете переупорядочение компилятора.
На X86
В архитектуре операция RMW всегда очищает буфер хранилища и поэтому является последовательной и последовательной последовательной операцией.
Вы можете сказать, что на X86
CPU, каждая операция RMW:
Когда используешь std::memory_order_relaxed
единственная гарантия состоит в том, что операция является атомной. Все что угодно вокруг операции может быть переупорядочено по желанию либо компилятором, либо процессором.
От https://en.cppreference.com/w/cpp/atomic/memory_order:
Расслабленная работа: нет синхронизации или заказа
ограничения, накладываемые на другие операции чтения или записи, только эта операция
атомарность гарантируется (см. «Расслабленный порядок» ниже)