У меня такой код:
#include <cstdint>
#include <atomic>
void myAtomicStore(std::atomic<int32_t>& i, const int32_t v) {
i.store(v, std::memory_order_release);
}
int myAtomicLoad(std::atomic<int32_t>& i, const int32_t v) {
return i.load(std::memory_order_acquire);
}
И (согласно this) GCC 8.1 перевел его (для x86_64) на:
myAtomicStore(std::atomic<int>&, int):
mov DWORD PTR [rdi], esi
ret
myAtomicLoad(std::atomic<int>&, int):
mov eax, DWORD PTR [rdi]
ret
Интересно, как инструкции mov
могут сделать все записи в память до того, как myAtomicStore()
станут видимыми для другого потока, когда он вызывает myAtomicLoad()
для той же переменной (или области памяти) - гарантированно стандартом C ++.
Я просмотрел Руководство Intel; и я не вижу ничего очевидного.
Спасибо!
mov
уже выполнила гарантию, упомянутую в стандарте C ++. Спасибо! - person HCSF   schedule 09.07.2018acquire
иrelease
, но неseq_cst
. Для этого вам нужноmfence
, а лучшеxchg [mem], eax
, чтобы создать хранилище с последовательным выпуском. (И, конечно же, операции RMW всегда seq_cst на x86 по крайней мере по сравнению с переупорядочением времени выполнения (переупорядочение времени компиляции все еще возможно для mo_relaxed). См. Может ли num ++ быть атомарным для 'int num'?: вам нужноlock add
в многоядерной системе.) - person Peter Cordes   schedule 09.07.2018lfence + sfence
могут быть более удачной целью для дублирования. - person Peter Cordes   schedule 09.07.2018*usually*, every load on x86/64 already implies acquire semantics and every store implies release semantics. This is why x86/64 is *often* said to be strongly ordered
. (курсив мой). - person Hadi Brais   schedule 09.07.2018