ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

深究可见性,原子性,有序性的解决方案之内存屏障

2022-03-19 12:06:24  阅读:170  来源: 互联网

标签:load 变量 深究 屏障 内存 有序性 操作 执行


   在了解内存屏障之前,我们先了解一下JMM模型的8种原子操作:

1.lock 锁定 : 把主内存中的一个变量标志为一个线程独享的状态

2.unlock 解锁 : 把主内存中的一个变量释放出来

3.read 读:将主内存中的变量读到工作内存中

4.load 加载:将工作内存中的变量加载到副本中

5.use 使用:当执行引擎需要使用到一个变量时,将工作内存中的变量的值传递给执行引擎

6.assign 赋值:将执行引擎收的的值赋值给工作内存中的变量

7.store 存储:将工作内存中的变量的值传到主内存中

8.write 写入:将store得到值放到主内存的变量中

并且JMM内存模型还规定了以上操作必须遵守的规则:

1.如果要把一个变量从主内存中复制到工作内存,就需要按顺寻地执行read和load操作, 如果把变量从工作内存中同步回主内存中,就要按顺序地执行store和write操作。但Java内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。

2.不允许read和load、store和write操作之一单独出现

3.不允许一个线程丢弃它的最近assign的操作,即变量在工作内存中改变了之后必须同步到主内存中。

4.不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步回主内存中。

5.一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量。即就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作。

6.一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现

7.如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始化变量的值

8.如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。

9.对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)

 

对于内存屏障而言,关注的就是store和load操作。

根据JMM模型规定,read和load,store和write必须同时出现,并且按照顺序执行,所以执行完load操作,必然是加载了主内存的值的,但不能保证这两操作时是原子性的,同样的道理,执行store也是一样的,都无法保证操作的原子性,那么内存屏障又是如何解决这个问题的呢?

首先看硬件层面的内存屏障:

1. lfence,是一种Load Barrier 读屏障。在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存加载数据,其实就是告诉操作系统,后面的值给我去主存中取。

2. sfence, 是一种Store Barrier 写屏障。在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存,其实就是把我写的这条数据直接刷到主存,看着和上面那条差不多都是刷最新的数据,但区别在于其他核心不一定会来取

3. mfence, 是一种全能型的屏障,具备ifence和sfence的能力,就是把当前缓存行的数据修改过的最新值刷入主存,其他的失效,重新从主存获取。
4. lock前缀也能实现类似的效果,它通过对总线/缓存行加锁,执行后面的指令,这个时候所有访问这条总线/缓存行的请求都会被阻塞,直到锁释放。lock指令可以保证前面的修改都会刷新到主存,并且释放锁后会使所有所有对应缓存行失效,这样就可以达到和内存屏障一样的效果

java中unsafe包也提供了类似的屏障:

public native void loadFence(); // 读屏障

public native void storeFence(); // 写屏障

public native void fullFence(); //两者都有

底层实现也都是差不多的,其实内存屏障的另外一个含义就是可以禁止重排序,屏障就是一道栅栏,前面的指令必须在前面执行完,后面的不能跳到前面执行,禁止代码过度优化。   最后我们再看下上面的问题,如何保证store load 和read write之间的原子性,最简单的就是加锁,但是这样的消耗太大,而内存屏障通过一道栅栏的形式,并保证缓存一致性,同样也实现了写与读之间的原子性。

标签:load,变量,深究,屏障,内存,有序性,操作,执行
来源: https://www.cnblogs.com/gmt-hao/p/16024098.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有