AFAIK C++ atomics (<atomic>
) -Familie bieten 3 Vorteile:C++ atomics und verkanten Sichtbarkeits
- primitive Befehle Unteilbarkeit (kein schmutziges liest),
- Speicherordnung (beide, für die CPU und Compiler) und
- Cross-Thread-Sichtbarkeit/Änderungen Ausbreitung.
Und ich bin mir nicht sicher über die dritte Kugel, werfen Sie einen Blick auf das folgende Beispiel.
#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;
}
Zuerst, bitte überprüfen Sie meine Annahmen in Code (insbesondere thread2
).
Zweitens meine Fragen sind:
Wie funktioniert die
a_flag
auf andere Kerne ausbreiten schreiben?Synchronisiert die
std::atomic
diea_flag
im Writer-Cache mit dem anderen Kerne-Cache (mit MESI oder irgendetwas anderes), oder die Propagierung ist automatisch?Angenommen, auf einer bestimmten Maschine ist ein Schreiben zu einem Flag atomar (think int_32 auf x86) Und wir haben keinen privaten Speicher zu synchronisieren (wir haben nur ein Flag) müssen wir Atomics verwenden?
Unter Berücksichtigung beliebtestene CPU-Architekturen (x86, x64, ARM v.whatever, IA-64), ist die Quer Kern Sicht (ich bin jetzt nicht Berücksichtigung Umordnungen) automatisch (aber möglicherweise verzögert), Oder müssen Sie bestimmte Befehle ausgeben, um Daten zu verbreiten?