O C ++ 11 padrão garante que memory_order_seq_cst evite a reordenação de StoreLoad de não atômica em torno de uma atômica?
O padrão C ++ 11 garante quememory_order_seq_cst
impede que StoreLoad reordene em torno de uma operação atômica para acessos de memória não atômica?
Como se sabe, existem 6std::memory_order
s em C ++ 11 e especificaquão regular, não atômica os acessos à memória devem ser solicitados em torno de uma operação atômica - Working Draft, Standard for Programming Language C ++ 2016-07-12:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
§ 29.3 Ordem e consistência
§ 29.3 / 1
A enumeraçãomemory_order especifica o detalhadomemória regular (não atômica) ordem de sincronização definida em 1.10 e pode fornecer o pedido de operação. Seus valores enumerados e seus significados são os seguintes:
Também conhecido, que esses 6 memory_orders impedem alguns desses reordenamentos:
Mas fazmemory_order_seq_cst
impedir o StoreLoad de reordenar em torno de uma operação atômica pararegular, não atômica acessos de memória ou apenas para outros atômicos com o mesmomemory_order_seq_cst
?
I.e. para impedir essa reordenação StoreLoad, devemos usarstd::memory_order_seq_cst
para STORE e LOAD, ou apenas para um deles?
std::atomic<int> a, b;
b.store(1, std::memory_order_seq_cst); // Sequential Consistency
a.load(std::memory_order_seq_cst); // Sequential Consistency
A semântica Acquire-Release é clara, ela especifica exatamente a reordenação de acesso à memória não atômica em operações atômicas:http://en.cppreference.com/w/cpp/atomic/memory_order
Para impedir a reordenação do StoreLoad, devemos usarstd::memory_order_seq_cst
.
Dois exemplos:
std::memory_order_seq_cst
para STORE e LOAD:Há simMFENCE
O StoreLoad não pode ser reordenado - 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
apenas para LOAD:não temMFENCE
O StoreLoad pode ser reordenado - 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
Além disso, se o compilador C / C ++ - usasse mapeamento alternativo do C / C ++ 11 para x86, o que liberaria o Buffer de Armazenamento antes do LOAD:MFENCE,MOV (from memory)
, então devemos usarstd::memory_order_seq_cst
para LOAD também:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html Como este exemplo é discutido em outra pergunta como abordagem (3):Faz alguma instrução sensata LFENCE nos processadores x86 / x86_64?
I.e. devemos usarstd::memory_order_seq_cst
para STORE e LOAD gerarMFENCE
garantido, que evita a reordenação do StoreLoad.
É verdade quememory_order_seq_cst
para carga atômica ou loja:
semântica specifi Acquire-Release - impedir: LoadLoad, LoadStore, StoreStore reordenando em torno de uma operação atômica pararegular, não atômica acessos de memória,
mas evite que o StoreLoad reordene em torno de uma operação atômicaapenas para outros átomos operações com o mesmomemory_order_seq_cst
?