Dlaczego GCC nie używa LOAD (bez ogrodzenia) i STORE + SFENCE dla Sequential Consistency?
Oto cztery podejścia do zapewnienia spójności sekwencyjnej w x86 / x86_64:
LOAD (bez ogrodzenia) i STORE + MFENCELOAD (bez ogrodzenia) i LOCK XCHGMFENCE + LOAD and STORE (bez ogrodzenia)LOCK XADD (0) i STORE (bez ogrodzenia)Jak napisano tutaj:http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
C / C ++ 11 Operacja implementacja x86
Load Seq_Cst: MOV (z pamięci)Zapisz Seq Cst: (LOCK) XCHG // alternatywa: MOV (do pamięci), MFENCEUwaga: istnieje alternatywne odwzorowanie C / C ++ 11 na x86, które zamiast blokować (lub ogradzać) magazyn Seq Cst blokuje / ogradza obciążenie Seq Cst:
Load Seq_Cst: LOCK XADD (0) // alternatywa: MFENCE, MOV (z pamięci)Store Seq Cst: MOV (do pamięci)GCC 4.8.2 (GDB w x86_64) używa pierwszego (1) podejścia doC ++ 11-std :: memory_order_seq_cst, tj. LOAD (bez ogrodzenia) i STORE + MFENCE:
std::atomic<int> a;
int temp = 0;
a.store(temp, std::memory_order_seq_cst);
0x4613e8 <+0x0058> mov 0x38(%rsp),%eax
0x4613ec <+0x005c> mov %eax,0x20(%rsp)
0x4613f0 <+0x0060> mfence
Jak wiemy, MFENCE = LFENCE + SFENCE. Następnie ten kod możemy przepisać do tego:LOAD(without fence) and STORE+LFENCE+SFENCE
Pytania:
Dlaczego nie musimy używać LFENCE tutaj przed LOAD i musimy używać LFENCE po STORE (ponieważ LFENCE ma sens tylko przed LOAD!)?Dlaczego GCC nie używa podejścia: LOAD (bez ogrodzenia) i STORE + SFENCE dla std :: memory_order_seq_cst?