c++ - x86 上的竞争条件

标签 c++ c x86 race-condition memory-barriers

谁能解释一下这个说法:

shared variables
x = 0, y = 0

Core 1       Core 2
x = 1;       y = 1;
r1 = y;      r2 = x;

如何在 x86 处理器上拥有 r1 == 0r2 == 0

来源 "The Language of Concurrency" by Bartosz Milewski .

最佳答案

问题可能是由于涉及 reordering of instructions 的优化而出现的。 .换句话说,两个处理器都可以分配 r1r2 before 分配变量 xy,如果他们发现这会产生更好的性能。这可以通过添加 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 = 1r2 = 1 的情况是不允许的(由于8.2.3.3 Stores are Not Reordered With Early加载保证),这意味着这些指令永远不会在单个内核中重新排序。

要将其与不同的架构进行比较,请查看这篇文章:Memory Ordering in Modern Microprocessors .您可以看到 Itanium (IA-64) 比 IA-32 架构进行更多的重新排序:

Possible CPU reorderings for various architectures

关于c++ - x86 上的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6623628/

相关文章:

c - FreeRTOS 在调度程序启动之前(或停止之后)排队等待 IO

c - fork 后重新创建死线程

assembly - x86 程序集中是否有任何指令仅存在于 64 位模式下?

c++ - 在 C++ 中,哪个析构函数被调用?

c++ - 如何检查类型是否为 int 的 typedef

c++ - 错误 C2784 : Could not deduce template argument

c++ - 您如何确定您正在运行最新的可执行文件?

c - Linux 内核字符驱动程序写入调用未按预期工作

c - c程序中链接的隐藏例程

x86 - 设置、清除 OF 和 TF 标志的汇编指令