AFAIK C++ atomics ( <atomic>
) 系列提供 3 个好处:
- 原始指令不可分割性(无脏读),
- 内存排序(对于 CPU 和编译器)和
- 跨线程可见性/更改传播。
而且我不确定第三个项目符号,因此请看以下示例。
#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;
}
首先,请在代码中验证我的假设(尤其是thread2
)。
其次,我的问题是:
a_flag
写入如何传播到其他内核?写入器缓存中的缓存是否与其他核心缓存(使用 MESI 或其他任何东西)
std::atomic
同步a_flag
,或者传播是自动的?假设在特定机器上对标志的写入是原子的(想想 x86 上的 int_32)并且我们没有任何私有内存要同步(我们只有一个标志)我们需要使用原子吗?
考虑到最流行的 CPU 架构(x86、x64、ARM v.whatever、IA-64),跨核心可见性(我现在不考虑重新排序)是自动的(但可能会延迟),或者您需要发出特定的命令传播任何数据?