Да, заказ по-прежнему применяется к оптимизации компилятора.
Кроме того, не совсем точно, что на x86 «операции атомной нагрузки всегда одинаковы».
На x86 все грузы, сделанные с помощью mov
, приобрели семантику, и все магазины, сделанные с помощью mov
, имеют семантику выпуска. Таким образом, acq_rel, acq и расслабленные нагрузки просты: mov
s, и аналогично acq_rel, rel и relaxed магазины (магазины acq и rel-нагрузки всегда равны расслабленным).
Это, однако, не обязательно верно для seq_cst: архитектура не гарантия seq_cst семантика для mov
. На самом деле набор инструкций x86 не имеет конкретной инструкции для последовательно согласованных нагрузок и хранилищ. Только операции атомарного чтения-изменения-записи на x86 будут иметь семантику seq_cst. Следовательно, вы можете получить семантику seq_cst для нагрузок, выполнив операцию fetch_and_add (lock xadd
) с аргументом 0 и семантикой seq_cst для магазинов, выполнив операцию обмена seq_cst (xchg
) и отбросив предыдущее значение.
Но вам не обязательно делать то и другое! Пока все магазины seq_cst выполняются с xchg
, нагрузки seq_cst могут быть реализованы просто с помощью mov
. Dually, если все нагрузки были сделаны с lock xadd
, магазины seq_cst могут быть реализованы просто с помощью mov
.
xchg
и lock xadd
намного медленнее, чем mov
. Поскольку у программы (как правило) больше нагрузок, чем магазинов, удобно хранить магазины seq_cst с xchg
, так что (более частые) нагрузки seq_cst могут просто использовать mov
. Эта деталь реализации кодируется в бинарном интерфейсе приложений (86I).На x86 совместимый компилятор должен скомпилировать хранилища seq_cst до xchg
, так что нагрузки seq_cst (которые могут отображаться в другой единицы перевода, скомпилированные с помощью другого компилятора) могут выполняться с помощью инструкции mov
.
Таким образом, в общем случае это не так, что seq_cst и получение нагрузок выполняются с той же инструкцией на x86. Это верно только потому, что ABI указывает, что хранилища seq_cst скомпилированы в xchg
.