谁能解释一下这个说法:
shared variables
x = 0, y = 0
Core 1 Core 2
x = 1; y = 1;
r1 = y; r2 = x;
如何在 x86 处理器上拥有 r1 == 0
和 r2 == 0
?
最佳答案
问题可能是由于涉及 reordering of instructions 的优化而出现的。 .换句话说,两个处理器都可以分配 r1
和 r2
before 分配变量 x
和 y
,如果他们发现这会产生更好的性能。这可以通过添加 memory barrier 来解决,这将强制执行排序约束。
引用 slideshow您在帖子中提到:
Modern multicores/languages break sequential consistency.
关于 x86 架构,最好的阅读资源是 Intel® 64 and IA-32 Architectures Software Developer’s Manual (章节 8.2 内存排序)。 8.2.1 和 8.2.2 节描述了由 Intel486, Pentium, Intel Core 2 Duo, Intel Atom, Intel Core Duo, Pentium 4, Intel Xeon 和 P6 系列处理器:一种称为处理器排序的内存模型,与旧 Intel386 架构的程序排序(strong ordering)相反(其中读取和写入指令始终按照它们在指令流中出现的顺序发出)。
手册描述了处理器排序内存模型的许多排序保证(例如Loads不与其他负载重新排序,Stores不与其他存储重新排序,商店不会用旧负载重新排序等),但它也描述了允许的重新排序规则,这会导致 OP 帖子中的竞争条件:
8.2.3.4 Loads May Be Reordered with Earlier Stores to Different Locations
另一方面,如果指令的原始顺序被切换:
shared variables
x = 0, y = 0
Core 1 Core 2
r1 = y; r2 = x;
x = 1; y = 1;
在这种情况下,处理器保证 r1 = 1
和 r2 = 1
的情况是不允许的(由于8.2.3.3 Stores are Not Reordered With Early加载保证),这意味着这些指令永远不会在单个内核中重新排序。
要将其与不同的架构进行比较,请查看这篇文章:Memory Ordering in Modern Microprocessors .您可以看到 Itanium (IA-64) 比 IA-32 架构进行更多的重新排序:
关于c++ - x86 上的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6623628/