0

我最近一直在阅读内存重新排序。我的问题是关于多线程场景。考虑下面的例子:

A = 0;
B = 0;

Thread 1 on Processor 1                       Thread 2 on Processor 2

    A = 100;                                      while(B== 0);
    B = 1;                                       //access A here

我一直在 X86-64 Windows 平台上编码,从未考虑过可以重新排序 A 和 B 的存储(在编译器级别或硬件级别),我可能最终在线程 2 中得到 B = 0 并发现 A 仍然存在0. 并且从来没有遇到过这样的代码的任何问题或讨厌的错误。是不是因为 x86-x64 是强排序的,windows C 编译器也是如此。

对于要在具有弱排序内存的任何其他平台上执行这样的代码,我是否需要确保在锁内更​​新和访问 A 和 B(假设底层锁实现使用内存屏障并确保仅在所有先前的加载和存储在所有处理器内核上都是可见的)。

谢谢

4

1 回答 1

1

是不是因为 x86-x64 是强排序的,windows C 编译器也是如此。

实际上,X86是一个不允许存储重新排序的强排序 CPU。所以所有的 CPU 内核都会遵守编译器发出的顺序。

但是,B在处理器 1 上被修改,而在处理器 2 上读取。没有同步的 C 内存模型不允许这样做(尝试最大编译器优化,它可能会停止工作)。

虽然锁定可用于在内核之间进行同步,但它可能会出现问题,因为您正在使用B. 如果在获得锁时发生这种情况,处理器 1 将无法更新该值。

正确的解决方案是使B atomic. 这将保证所有级别的正确排序。

于 2017-07-08T19:04:35.900 回答