AFAIK C++ Atomics (<atomic>
) rodzina dostarczyć 3 zalety:C++ Atomics i widoczność cross-gwint
- prymitywny instrukcji niepodzielność (nie brudny czyta)
- zamawiania pamięci (zarówno dla CPU i kompilatora) oraz
- Przejrzystość widoczności/zmiany poprzeczne.
I nie jestem pewien co do trzeciej kuli, więc spójrz na poniższy przykład.
#include <atomic>
std::atomic_bool a_flag = ATOMIC_VAR_INIT(false);
struct Data {
int x;
long long y;
char const* z;
} data;
void thread0()
{
// due to "release" the data will be written to memory
// exactly in the following order: x -> y -> z
data.x = 1;
data.y = 100;
data.z = "foo";
// there can be an arbitrary delay between the write
// to any of the members and it's visibility in other
// threads (which don't synchronize explicitly)
// atomic_bool guarantees that the write to the "a_flag"
// will be clean, thus no other thread will ever read some
// strange mixture of 4bit + 4bits
a_flag.store(true, std::memory_order_release);
}
void thread1()
{
while (a_flag.load(std::memory_order_acquire) == false) {};
// "acquire" on a "released" atomic guarantees that all the writes from
// thread0 (thus data members modification) will be visible here
}
void thread2()
{
while (data.y != 100) {};
// not "acquiring" the "a_flag" doesn't guarantee that will see all the
// memory writes, but when I see the z == 100 I know I can assume that
// prior writes have been done due to "release ordering" => assert(x == 1)
}
int main()
{
thread0(); // concurrently
thread1(); // concurrently
thread2(); // concurrently
// join
return 0;
}
Najpierw proszę potwierdzić moje założenia w kodzie (szczególnie thread2
).
Po drugie, moje pytania są następujące:
jaki sposób
a_flag
napisać rozprzestrzeniać się do innych rdzeni?Czy
std::atomic
synchronizujea_flag
w pamięci podręcznej programu piszącego z inną pamięcią podręczną rdzeni (przy użyciu MESI lub cokolwiek innego), czy propagacja jest automatyczna?Zakładając, że na konkretnym komputerze zapis na flagę jest atomowy (pomyśl int_32 na x86) A my nie mamy pamięci prywatnej do zsynchronizowania (mamy tylko flagę) czy potrzebujemy atomów?
Biorąc pod uwagę najbardziej popularnych architektur procesorów (x86, x64, ARM v.whatever, IA-64), jest widoczność przekroju rdzenia (jestem teraz nie rozważają reorderings) automatyczne (ale potencjalnie opóźnione), lub musisz wydać konkretne polecenia, aby propagować dowolne dane?