我无法理解JSR-133 Coookbook中的 StoreLoad 屏障的定义。
这是否意味着没有其他 StoreLoad 屏障,即使其他处理器对同一内存位置进行了写入并刷新到缓存之间,处理器也可以将存储Store1写入其写缓冲区并从其写缓冲区加载此存储的值。 Store1和Load1?
最佳答案
是的,这是可能的,具体取决于内存订购模型。
写缓冲区通常是预先调度的,这意味着外界尚无法观察其中的存储。但是,为了获得更好的性能,大多数微体系结构允许在同一线程上执行较年轻的负载,并且如果地址与商店的地址匹配,则可以执行数据转发以使程序尽可能快地继续运行,同时使负载看起来像这是在商店之后完成的。
这对于线程内一致性工作正常,但是当外部处理器访问相同的地址并可能更改数据时,对于负载而言,看到它可能为时已晚(尽管在许多CPU上,如果负载未负载,它们仍可能会被捕获)尚未完成,机器将自行修复)。
我不完全确定引用的意思是什么,但是我认为在这种情况下可以更好地证明这一点:
CPU0: CPU1:
store [x]<--1
store [x]<--2
store [y]<--2
load r1<--[x]
load r2<--[y]
从理论上讲,没有障碍的可能结果是
r1 == 1, r2 == 2
,这意味着CPU1的两个存储都已执行(因为我们从2
读取了[y]
),但是某种程度上[x]
的旧值仍然存在(因为已转发)。我真的不喜欢这个示例,首先是因为,正如我说的那样,即使执行后,大多数CPU仍应成功监听该负载的旧值。其次-过于复杂,因为他们坚持要求:
这是错误的,本地址不同时,也必须设置障碍,如以下(经典)示例所示:
CPU0: CPU1:
store [x]<--1 store [y]<--1
load r1<--[y] load r2<--[x]
这里的地址是不同的,由于负载的无序执行,即使两个负载都读取旧值(即使必须执行两个存储才能到达旧值),仍然需要一个屏障。请注意,这是与提出的问题不同的问题(存储到负载转发),但是它证明了报价是错误的。
关于java - StoreLoad内存屏障,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21148085/