Гарантирует ли стандарт C ++ 11, что memory_order_seq_cst предотвращает переупорядочение StoreLoad неатомных вокруг атомарных?
Гарантирует ли стандарт C ++ 11, чтоmemory_order_seq_cst
предотвращает переупорядочение StoreLoad вокруг атомарной операции для неатомарного доступа к памяти?
Как известно, есть 6std::memory_order
s в C ++ 11, и его указываеткак регулярно, не атомно доступ к памяти должен быть упорядочен вокруг атомарной операции - рабочий проект, стандарт для языка программирования C ++ 2016-07-12:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§ 29.3 Порядок и последовательность
§ 29.3 / 1
Переченьmemory_order указывает подробноеобычная (неатомарная) память порядок синхронизации, как определено в 1.10, и может предусматривать порядок действий. Перечисленные значения и их значения следующие:
Также известно, что эти 6 memory_orders предотвращают некоторые из этих переупорядочений:
Но делает лиmemory_order_seq_cst
предотвратить переупорядочение StoreLoad вокруг атомарной операции дляобычный, не атомный доступ к памяти или только для других атомных с тем жеmemory_order_seq_cst
?
То есть чтобы предотвратить этот переупорядочивание StoreLoad мы должны использоватьstd::memory_order_seq_cst
для STORE и LOAD, или только для одного из них?
std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // Sequential Consistency
a.load(std::memory_order_seq_cst); // Sequential Consistency
О семантике Acquire-Release все ясно, она точно определяет не-атомарное переупорядочение доступа к памяти через атомарные операции:http://en.cppreference.com/w/cpp/atomic/memory_order
Чтобы предотвратить переупорядочение StoreLoad, мы должны использоватьstd::memory_order_seq_cst
.
Два примера:
std::memory_order_seq_cst
как для магазина, так и для нагрузки:естьMFENCE
StoreLoad не может быть переупорядочен - GCC 6.1.0 x86_64:https://godbolt.org/g/mVZJs0
std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // can't be executed after LOAD
a.load(std::memory_order_seq_cst); // can't be executed before STORE
std::memory_order_seq_cst
только для НАГРУЗКИ:нетMFENCE
StoreLoad можно переупорядочить - GCC 6.1.0 x86_64:https://godbolt.org/g/2NLy12
std::atomic<int> a, b;
b.store(1, std::memory_order_release); // can be executed after LOAD
a.load(std::memory_order_seq_cst); // can be executed before STORE
Также, если C / C ++ - компилятор использовал альтернативное отображение C / C ++ 11 на x86, которое сбрасывает буфер хранилища перед LOAD:MFENCE,MOV (from memory)
поэтому мы должны использоватьstd::memory_order_seq_cst
для нагрузки тоже:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html Как этот пример обсуждается в другом вопросе, как подход (3):Имеет ли смысл инструкция LFENCE в процессорах x86 / x86_64?
То есть мы должны использоватьstd::memory_order_seq_cst
для STORE и LOAD для генерацииMFENCE
Гарантируется, что предотвращает переупорядочение StoreLoad.
Это правда, чтоmemory_order_seq_cst
для атомной нагрузки или магазина:
Определить семантику Acquire-Release - предотвратить: LoadLoad, LoadStore, StoreStore переупорядочение вокруг атомарной операции дляобычный, не атомный доступ к памяти,
но предотвратите переупорядочение StoreLoad вокруг атомарной операциитолько для других атомных операции с тем жеmemory_order_seq_cst
?