jed*_*dib 6 c++ atomic memory-model memory-barriers stdatomic
我不确定我是否完全理解C ++ 11中原子性和内存排序的概念(我可能全都错了)。让我们以这个简单的单线程示例为例:
int main()
{
std::atomic<int> a(0);
std::atomic<int> b(0);
a.store(16);
b.store(10);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在此单线程代码中,如果a和b不是原子类型,则编译器可能以某种方式对指令进行了重新排序,例如,在汇编代码中,例如,我有一条将10赋给'b'的move指令,然后将将16分配给“ a”。因此,对我来说,作为原子变量,它可以确保我在源代码中声明的“ b移动指令”之前拥有“移动指令”。之后,处理器将带有执行单元,预取指令以及乱序框。无论汇编代码中的指令顺序如何,该处理器都可以在“ a指令”之前处理“ b指令”。
以我的理解,这就是内存排序模型出现的地方。从那时起,如果我让默认模型顺序一致。一个可以保证我清除主内存中的这些值(10和16)将遵守我在源代码中存储的顺序。这样,处理器将开始清空寄存器或高速缓存,其中将16存储到主存储器中以进行更新'a',然后处理器将清空主存储器中的10'b'。
这样的行为的确使我了解到,如果我使用宽松的内存模型。只有最后一部分不能保证,因此主内存中的刷新可能完全混乱。
抱歉,如果您在阅读我时遇到麻烦,我的英语仍然很差。但是谢谢你们的时间。
C++ 内存模型是关于抽象机器和值可见性,而不是关于“主内存”、“写入队列”或“刷新”等具体事物。
在您的示例中,内存模型指出,由于写入a发生在写入之前b,因此任何从 读取 10 的线程都b必须在随后从 读取时a看到 16(当然,除非此后已被覆盖)。
这里重要的是建立事前关系和价值可见性。如何映射到缓存和内存取决于编译器。在我看来,最好停留在抽象级别上,而不是尝试将模型映射到您对硬件的理解,因为