【发布时间】:2011-11-12 21:32:42
【问题描述】:
我知道现代 CPU 可能会乱序执行,但它们总是按 wikipedia 的描述按顺序退出结果。
“Out of Oder 处理器及时用其他准备好的指令填充这些“插槽”,然后在最后对结果重新排序,以使指令看起来正常处理。 "
现在据说使用多核平台时需要内存栅栏,因为由于乱序执行,x的值可能会在此处打印错误。
Processor #1:
while f == 0
;
print x; // x might not be 42 here
Processor #2:
x = 42;
// Memory fence required here
f = 1
现在我的问题是,由于乱序处理器(我假设多核处理器的核心)总是按顺序退出结果,那么内存栅栏的必要性是什么。多核处理器的内核是否只看到从其他内核退出的结果,或者它们也看到正在进行的结果?
我的意思是在我上面给出的例子中,当处理器 2 最终将退出结果时,x 的结果应该在 f 之前,对吗?我知道在乱序执行期间,它可能在 x 之前修改了 f,但它一定没有在 x 之前退出它,对吧?
现在,随着按顺序退出结果和缓存一致性机制,为什么您还需要 x86 中的内存栅栏?
【问题讨论】:
-
请注意,内存栅栏总是成对出现在正确的代码中:当两个线程通信时,每个线程必须执行一些内存访问顺序(=栅栏)。通常,这些栅栏之一具有释放语义,另一个具有获取语义。在您的伪代码中,处理器#2 应该在分配之间执行写栅栏(释放语义),处理器#1 应该在循环和
print之间添加一个读栅栏(获取语义)。在特定平台上可能不需要某些栅栏,但任何源代码都应包含这两个栅栏(可能编译为 noops)。
标签: c x86 cpu memory-barriers memory-fences