尽管Memory barriers: a hardware view for software hackers这本书被认为是非常古老的书(由作者看来,保罗本人也回答了this question),但我发现它是围绕记忆顺序建立心理模型的绝佳帮手。
有一点我不理解:
让我们考虑存在内存障碍的页面:
步骤4指出“ b = 1”已写入存储缓冲区,因为“ a = 1”尚未写入高速缓存。
我无法理解的是为什么在下一页:
在步骤3上,即使在“ a = 1”和“ a = 1”之后还没有存储屏障,“ b = 1”也会写入高速缓存行?在上一页之后,仅当将包含“ a = 1”的存储缓冲区写入高速缓存时,才应在步骤10之后(或之内)将“ b = 1”写入高速缓存。
答案 0 :(得分:1)
您发布的pdf与问题中的屏幕截图不同,因此我认为旧版本不正确(或者至少不够精确)。
第4.3章。实际上是从以下注释开始的:
让我们假设CPU将无效请求排队,但立即对其做出响应。这种方法最大程度地减少了看到的缓存无效延迟 由CPU进行存储,但可以克服内存障碍,如以下示例所示。
序列与您发布的序列也有些不同:
CPU 0执行a=1
。相应的缓存行在CPU 0的缓存中是只读的,因此CPU 0将新值“ a”放入其存储缓冲区并发送“无效”消息,以便从CPU 1的缓存中刷新相应的缓存行。 p>
CPU 1执行while (b==0) continue;
,但是包含“ b”的高速缓存行不在其高速缓存中。因此,它发送“已读”消息。
CPU 1收到CPU 0的“无效”消息,将其排队,然后立即对其进行响应。
CPU 0收到来自CPU 1的响应,因此可以自由地经过上面第4行上的smp_mb()
,将“ a”的值从其存储缓冲区移动到其缓存行。 / p>
我认为这是一种假设的情况,但是考虑到这一点,显然有问题的部分是CPU 1在实际使高速缓存无效之前承认“无效”消息,这使CPU 0认为它可以继续进行。