【问题标题】:StoreLoad Memory BarrierStoreLoad 内存屏障
【发布时间】:2014-02-04 13:14:01
【问题描述】:

我无法理解JSR-133 CoookbookStoreLoad 障碍的定义。

商店1;存储加载;加载2

StoreLoad 屏障使用 Store1 的数据值而不是从更新的存储到由不同处理器执行的相同位置的数据值来防止后续加载不正确。

这是否意味着如果没有 StoreLoad 屏障,处理器可以将 Store1 存储到其写入缓冲区并从其写入缓冲区加载此存储的值,即使其他处理器写入相同的内存位置并刷新到 Store1 和 Load1 之间的缓存?

【问题讨论】:

  • 如果没有 StoreLoad 屏障,处理器可以只将数据写入其缓冲区而不与其他处理器同步(例如通过写入主存储器),因此另一个处理器可以从其缓冲区或从主存储器加载数据内存,但不会获得最新的值。
  • 假设有一个全局变量 x。处理器 P1 写入 x(将 1 存储到 P1 的写入缓冲区),然后处理器 P2 将其对 x 的写入刷新到高速缓存(即使 x 的 P1 高速缓存行无效)。 P1 是否仍会从其写入缓冲区加载 x (Load2)?
  • 如果没有使用 StoreLoad 屏障,没有什么会迫使 P1 不这样做!因此,共享状态的每次访问(写入和读取)都必须同步以保证线程安全。

标签: java multithreading concurrency cpu-architecture java-memory-model


【解决方案1】:

是的,这是可能的,具体取决于内存排序模型。

写缓冲区通常是预先调度的,这意味着外部世界还无法观察到其中的存储。但是,为了获得更好的性能,大多数微架构允许在同一线程上执行较年轻的加载,并且如果地址与存储的地址匹配 - 可以执行数据转发以使程序尽可能快地继续,同时使加载看起来好像它是在商店之后完成的。

这对于线程内的一致性很好,但是当外部处理器访问相同的地址并可能更改数据时,负载可能会为时已晚(尽管在许多 CPU 上,如果负载仍然会被捕获)尚未完成,机器将自行修复)。

我不完全确定引用的意思是什么,但我认为可以通过这种情况更好地说明:

CPU0:                              CPU1: 
store [x]<--1                      
                                   store [x]<--2
                                   store [y]<--2
load  r1<--[x]                     
load  r2<--[y]                     

没有障碍的可能结果(理论上)是r1 == 1, r2 == 2,这意味着 CPU1 的两次存储都已经执行(因为我们从[y] 读取了2),但不知何故[x] 的旧值有幸存下来(因为它被转发了)。

我不太喜欢这个例子,首先,正如我所说,大多数 CPU 应该成功地窥探到该负载的旧值,即使在它执行之后也是如此。其次 - 它过于复杂,因为他们坚持声称:

StoreLoad 仅用于将存储与在屏障之前存储的相同位置的后续加载分开

这是错误的,当地址不同时也需要设置屏障,如以下(经典)示例所示:

CPU0:                              CPU1: 
store [x]<--1                      store [y]<--1
load  r1<--[y]                     load r2<--[x]

这里的地址是不同的,并且仍然需要一个屏障来防止两个加载都读取旧值的情况(即使两个存储都必须执行才能到达那里),这要归功于加载的无序执行.请注意,这与提出的问题(存储到负载转发)是不同的问题,但它证明了引用是错误的。

【讨论】:

  • 可能值得注意的是,有两种内存一致性模型:编程语言模型(在本例中为 Java)和硬件模型(硬件可以在每个程序的基础上支持不同的一致性模型; IIRC,SPARCv9 支持 3 种模型,但尚不清楚支持更强一致性的任何实现是否在程序指定时有效地利用了更宽松的一致性)。一种语言的一致性模型可能允许编译器重新排序访问,因此理论上不使用屏障可能会导致顺序一致性硬件出现不希望的行为。
  • CPU 首先检查存储缓冲区。只有当地址不存在时才会发出加载请求,否则会加载来自存储缓冲区的值。
  • @Mikhail,对,这正是导致潜在问题的原因——过早的前锋。顺便说一句,它也不影响我的第二个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2011-07-05
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多