首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LoadLoad屏障到底是做什么的?

LoadLoad屏障到底是做什么的?
EN

Stack Overflow用户
提问于 2013-03-12 11:59:16
回答 2查看 2.3K关注 0票数 12

在Java中,当有两个线程共享以下变量时:

代码语言:javascript
复制
int a;
volatile int b;

如果线程1做到了:

代码语言:javascript
复制
a = 5;
b = 6;

然后在这两个指令之间插入一个StoreStore屏障,'a‘被冲回主内存。

现在,如果线程2做到了:

代码语言:javascript
复制
if(b == 6)
 a++;

在之间插入一个LoadLoad屏障,并且我们保证,如果新值'b‘是可见的,那么'a’的新值也是可见的。但这实际上是如何实现的呢?LoadLoad是否使CPU缓存/寄存器失效?或者只是指示CPU从CPU中再读取变量的值?

我发现了有关LoadLoad屏障(http://gee.cs.oswego.edu/dl/jmm/cookbook.html)的信息:

LoadLoad屏蔽了顺序: Load1;LoadLoad;Load2,确保在Load2访问数据和加载所有后续加载指令之前加载load 1的数据。通常,在执行推测负载和/或无序处理的处理器上需要显式的LoadLoad屏障,在这些处理中等待负载指令可以绕过等待存储。在保证始终保持负载排序的处理器上,这些障碍相当于无操作。

但这并不能真正解释这是如何实现的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-12 12:46:39

我将举一个例子说明如何实现这一目标。您可以阅读更多关于细节这里的内容。对于x86处理器,正如您所指出的那样,LoadLoad最终是不操作的。在我链接的文章中,Mark指出

道格列出了StoreStore,LoadLoad和LoadStore

因此,从本质上讲,唯一需要的障碍是用于x86体系结构的一个x86。那么,这是如何在低水平上实现的呢?

以下是博客的摘录:

,这是它为易失性和非易失性读取生成的代码:

代码语言:javascript
复制
nop                       ;*synchronization entry
mov    0x10(%rsi),%rax    ;*getfield x

和用于易失性写入:

代码语言:javascript
复制
xchg   %ax,%ax
movq   $0xab,0x10(%rbx)
lock addl $0x0,(%rsp)     ;*putfield x

lock指令是道格食谱中列出的StoreLoad。但是,锁指令还将所有读取与其他进程同步,如挂牌

锁定指令可用于同步由一个处理器编写的数据和由另一个处理器读取的数据。

这减少了为易失性负载发出LoadLoad LoadStore屏障的开销。

话虽如此,我还是要重申亚述人所指出的。发生这种情况对开发人员来说并不重要(如果您对处理器/编译器实现者感兴趣,那就另当别论了)。volatile关键字是一种接口,表示

  1. 您将获得最新的阅读,这是由另一个线程编写的。
  2. 您不会被JIT编译器优化烧坏。
票数 5
EN

Stack Overflow用户

发布于 2013-03-12 15:40:44

如果该LoadLoad计算结果为no-op,那么线程2可以继续使用缓存的值。

这包括在烹饪书中的“可以点菜”表中。

编程顺序是

代码语言:javascript
复制
read b
read a
write a

所谓“缓存a",意思是代码被重新排序。

代码语言:javascript
复制
read a
...
read b

这种重新排序是被禁止的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15360598

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档