mfence, lfence, sfence什么作用?
mfence, lfence, sfence什么作用?
// src/backend/utils/rac/lock_free_queu.array_spsc_queue.c
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
#define wmb() asm volatile("sfence" ::: "memory")
就是保证内存访问的串行化,内部操作就是在一系列内存访问中添加若干延迟,保证此指令之后的内存访问发生在此指令之前的内存访问完成之后(不出现重叠)。
lfence 读串行化
sfence 写串行化
mfence 读写都串行化
参考
内存屏障
为什么需要内存屏障?
由于现代的操作系统都是多处理器.而每一个处理器都有自己的缓存,并且这些缓存并不是实时都与内存发生信息交换.这样就可能出现一个cpu上的缓存数据与另一个cpu上的缓存数据不一致的问题.而这样在多线程开发中,就有可能导致出现一些异常行为. 而操作系统底层为了这些问题,提供了一些内存屏障用以解决这样的问题
内存屏障的作用
1. 阻止屏障两边的指令重排序
2. 强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效(意思就是确保读到的数据都是内存中的最新的数据,确保数据的有效性)
内存屏障的分类
硬件层提供了一系列的内存屏障 memory barrier / memory fence(Intel的提法)来提供一致性的能力。拿X86平台来说,有几种主要的内存屏障
1. lfence,是一种Load Barrier 读屏障。在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存加载数据
2. sfence, 是一种Store Barrier 写屏障。在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存
3. mfence, 是一种全能型的屏障,具备ifence和sfence的能力
4. Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为CPU指令级的一种锁。它后面可以跟ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG等指令。
Lock前缀实现了类似的能力.
1. 它先对总线/缓存加锁,然后执行后面的指令,最后释放锁后会把高速缓存中的脏数据全部刷新回主内存。
2. 在Lock锁住总线的时候,其他CPU的读写请求都会被阻塞,直到锁释放。Lock后的写操作会让其他CPU相关的cache line失效,从而从新从内存加载最新的数据。这个是通过缓存一致性协议做的。
内存屏障使用例子
LoadLoad屏障(读读屏障):对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
StoreStore屏障(写写屏障):对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
LoadStore屏障(读写屏障):对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
StoreLoad屏障(写读屏障):对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。
java中内存屏障的常见例子
通过 Synchronized关键字包住的代码区域,当线程进入到该区域读取变量信息时,保证读到的是最新的值.这是因为在同步区内对变量的写入操作,在离开同步区时就将当前线程内的数据刷新到内存中,而对数据的读取也不能从缓存读取,只能从内存中读取,保证了数据的读有效性.这就是插入了StoreStore屏障
使用了volatile修饰变量,则对变量的写操作,会插入StoreLoad屏障.
其余的操作,则需要通过Unsafe这个类来执行.
mfence, lfence, sfence什么作用?相关推荐
- 分析Volatile的作用及底层实现原理,面试问一点都不慌!
文章简介 分析volatile的作用以及底层实现原理,这也是大公司喜欢问的问题 内容导航 volatile的作用 什么是可见性 volatile源码分析 01.volatile的作用 在多线程中,vo ...
- 线程安全问题的本质详解: 原子性、有序性、可见性
内容导航 volatile的作用 什么是可见性 volatile源码分析 一.volatile的作用 在多线程中,volatile和synchronized都起到非常重要的作用,synchronize ...
- Java程序员需要掌握的计算机底层知识(一):CPU基本组成、指令乱序执行、合并写技术、非同一访问内存 NUMA
一些书籍 读书的原则:不求甚解,观其大略 你如果进到庐山里头,二话不说,蹲下头来,弯下腰,就对着某棵树某棵小草猛研究而不是说先把庐山的整体脉络跟那研究清楚了,那么你的学习方法肯定效率巨低而且特别痛苦, ...
- Java需要掌握的底层知识_Java程序员应该掌握的底层知识
缓存 缓存行: 缓存行越大,局部性空间效率越高,但读取时间慢 缓存行越小,局部性空间效率越低,但读取时间快 取一个折中值,目前多用: 64字节 public class CacheLinePaddin ...
- Java并发编程实战_一线大厂架构师整理:java并发编程实践教程
并发编程是Java语言的重要特性之一, 在Java平台上提供了许多基本的并发功能来辅助开发多线程应用程序.然而,这些相对底层的并发功能与上层应用程序的并发语义之间并不存在一种简单而直观的映射关系.因此 ...
- synchronized.1
用户态与内核态 JDK早期,synchronized 叫做重量级锁, 因为申请锁资源必须通过kernel, 系统调用 ;hello.asm ;write(int fd, const void *buf ...
- linux与RMB的关系,linux mb()/rmb()/wmb()
在阅读linux 2.6.23内核代码中遇到mb()/rmb()/wmb() 这几个宏,不明白如何使用, 在分析其汇编代码后,大概的了解了这和内存屏障有关,代码如下: #define X86_FEAT ...
- I/O函数 writel __raw_writel mb()/rmb()/wmb()
在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...
- 【读书笔记】Java并发编程的艺术
第一章 并发编程的挑战 上下文切换 上下文切换概述 切出:一个线程被剥夺处理器的使用权而暂定运行 切入:一个线程被选中占用处理器或者继续运行 上下文:在这种切入切出的过程中,操作系统需要保存和恢复相应 ...
最新文章
- Linux搭建BT下载服务器,linux下搭建bt服务器–xbt篇
- django 模板语言之 simple_tag 自定义模板
- php数据库访问辅助类,php+MySQL实战案例【二】php数据库辅助类
- linux该专接本还是工作_是该专接本还是直接工作?学历和经验哪个重要?
- Angular里使用createEmbeddedView动态加入新的模板元素
- t3s java_关于JAVA的this关键字
- UI组件-UIPickerView
- linux数组大小排序,Linux如何使用awk进行数组排序
- Android通讯录(一)
- 天翼网关服务器无响应,教你使用天翼网关软件突然打不开的解决方法
- 被野性消费的黄桃罐头,还能火多久!
- 【LOJ 10064】黑暗城堡
- spleeter分离伴奏和人声
- 详述win10下配置tensorflow-gpu
- wcdma码片速率_WCDMA中3.84M码片速率的由来
- Shell语法----概论
- 想一想就感觉到生活还是充满很多正能量的
- 陕科大计算机专业好转吗,陕西人眼里的陕科大怎么样?211为什么没给陕科大?...
- 主流开源流媒体服务器有哪些?
- [源码和文档分享]基于JSP实现的试题库管理系统
热门文章
- 成都专业计算机职称考试地点,2018年12月四川成都职称计算机考试报名通知
- Jsuop Whitelist
- 总结使用labelimg打YOLOv5格式的标签过程中掉过的坑
- hadoop mpp oracle,请教一下MPP 与 Hadoop是什么关系?
- 设计模式之Facade(外观 总管 Manager)
- 猫架的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- C语言大作业——消灭星星
- 蛋壳再陷风波,长租公寓们如何才能“长”久?
- 《嵌入式Linux开发实用教程》
- 分享整理的免费API接口