首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >记忆屏障和松弛记忆模型

记忆屏障和松弛记忆模型
EN

Stack Overflow用户
提问于 2011-08-22 19:22:47
回答 2查看 478关注 0票数 2

目前,我正在努力提高对内存屏障、锁和内存模型的理解。

据我所知,存在四种不同类型的松弛,即Write -> Read,Write -> Write,Read -> Write和Read -> Read。x86处理器只允许写入->读取松弛,这通常被称为总存储顺序( Total Store Order )。部分存储顺序(PSO)允许进一步的Write->Write松弛,而宽松存储顺序(RSO)允许所有上述松弛。

此外,还存在三种类型的记忆障碍:释放、获取和两者同时存在。锁可以只使用获取和释放屏障,有时使用完全屏障(.Net)。

现在考虑以下示例:

代码语言:javascript
复制
// thread 0
x = 1
flag = 1

//thread 1
while (flag != 1);
print x

我目前的理解告诉我,如果我在TSO机器上运行这段代码,就不需要额外的内存障碍。如果是PSO机,我需要在x=1和flag =1之间设置释放屏障,以确保线程1在flag =1的情况下获得x的实际值。如果是RSO机,我需要在while(flag != 1)和print x之间进一步设置获取屏障,以防止线程1提前读取x的值。

我的观察结果正确吗?

EN

回答 2

Stack Overflow用户

发布于 2011-09-01 10:10:27

我认为您的代码示例与此question中的代码示例非常接近

也就是说,对于RSO,您需要比您所描述的更多的内存屏障,例如,在while之前为线程1提供新鲜性保证的屏障。

我不确定TSO和PSO部分,希望这能有所帮助,因为我也试图理解这个问题中的记忆障碍和一些相关的问题

票数 0
EN

Stack Overflow用户

发布于 2021-03-13 23:14:11

可以在软件(编译器)和硬件级别上进行重新排序。所以请记住这一点。因此,即使在TSO CPU上,这两个存储不会被重新排序,也不会阻止编译器重新排序这两个存储(或两个加载)。所以flag需要是一个同步变量,flag的存储需要是一个释放存储,flag的加载需要是一个获取加载。

但是如果我们假设上面的代码表示X86指令:

然后,使用TSO,上述操作将正常工作,因为它将防止2个存储和2个加载被重新排序。

但使用PSO,上述操作可能会失败,因为这两个商店可能会被重新排序。

因此,想象一下你将拥有以下内容:

代码语言:javascript
复制
b = 1
x = 1
flag = 1

由此b是与flag相同的高速缓存线上的值。然后,通过写合并,可以合并flag=1b=1,因此flag=1可以超过x=1,因此在x=1之前变得全局可见。

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

https://stackoverflow.com/questions/7146736

复制
相关文章

相似问题

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