内存屏障:软件黑客的硬件视图示例 3

Alb*_*ymk 4 memory-barriers

我正在从原始论文“内存屏障:软件黑客的硬件视图”中复制该图的文本。

\n
\n

表 4 显示了由 CPU 0、1 和 2 同时执行的三个代码片段。所有变量最初都为零。

\n

请注意,CPU 1 和 CPU 2 都无法继续执行第 5 行,直到它们在第 3 行看到 CPU 0\xe2\x80\x99s 分配给 \xe2\x80\x9cb\xe2\x80\x9d。一旦 CPU 1 和 2 执行了它们的如果第 4 行上有内存屏障,它们都保证能看到第 2 行内存屏障之前的 CPU 0 的所有分配。同样,第 8 行上的 CPU 0\xe2\x80\x99s 内存屏障与第 8 行上的 CPU 1 和 2 的内存屏障配对4,这样CPU 0不会执行第9行对\xe2\x80\x9ce\xe2\x80\x9d的赋值,直到它对\xe2\x80\x9ca\xe2\x80\x9d的赋值对两个CPU都可见之后其他CPU。因此,第 9 行的 CPU 2\xe2\x80\x99s 断言保证不会触发。

\n
\n

在此输入图像描述

\n

对我来说,CPU0 上的第 6-9 行似乎根本没有必要,因为 CPU 0 的第 2 行的内存屏障和 CPU 1&2 的第 4 行的内存屏障保证了 的效果被b=1拾取,并且之前的所有存储也是如此a=1。然后,断言e == 0 || a == 1总是成功。

\n

我不知道我是否忽略了什么。任何澄清表示赞赏。

\n

小智 5

将第 6-9 行留在 CPU 0 之外肯定会阻止assert() 触发。话又说回来,假设e初始化为零,那么将删除除断言之外的所有代码。然而,这两种修改都是无济于事的。e==1&&a==0相反,断言的关键点是“CPU 2 是否有可能看到其执行结束时的状态?”的问题。以这种方式看待它应该迫使您思考什么值以什么顺序在哪里传播。

但您忽略的主要事情是,这篇论文非常古老,从那时起,在理解和形式化内存排序方面已经取得了巨大的进步。我正在向《并行编程很难吗?如果是这样,你能做什么?》添加一个新的内存排序章节。 与此同时,这里这里的两篇 LWN 文章可能会有所帮助。

或者,如果您想查看本书的当前状态,git clone git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/perfbook.git.