当前位置: 首页 > news >正文

linux 内存屏障(barrier)分析

谈起内存屏障,大家感觉这个"玩意儿"很虚,不太实际,但是内核代码中又广泛地可以看到起身影。内存屏障,英文barrier,这个"玩意儿"它还不太好去定义它。barrier,中文翻译为栅栏,栅栏大家都见过,现实生活中就是防止他人或者动物非法闯入而用来进行隔离用的工具。再进一步,既然是防止闯入,那就是要保护栅栏内的东西。所以在linux 内核中,内存屏障用于保护内存的访问。

1、什么需要保护

下面来谈谈内存屏障到底保护什么。

比如cpu0执行 a = 1 这条指令时,假设a所在cache line已经在cpu1的 L1 cache中,cpu0 先要获取a所在的cache line到cpu0的L1cache中,由于是写操作,需要改写a的值,需要再总线上发送invalid消息让其他cpu使无效其cache中a的值,等待其他cpu应答后,cpu0才能改写a的值,这样才能保证cache一致性。

 等待其他cpu上使无效消息的应答期间造成了cpu0的无效等待,浪费时间。于是cpu设计者开始修改CPU设计,出现了使无效队列以及write buffer这些内部部件用来加速cpu的执行。具体内容读者可以查阅其他文章。

提升CPU执行效率(硬件层面)和编译器的优化使得指令重排序(软件层面)给程序员带来了负担,需要程序去进行进行内存访问顺序的维护及保序。

2、ARM提供的指令

ARM提供了如下指令来进行内存屏障的处理:

DMB:Data Memory Barrier,数据存储屏障

DSB:Date Synchronization Barrier,数据同步屏障

ISB:Instruction Synchronization Barrier,指令同步屏障

DMB和DSB的一个本质区别,DMB针对的是memory的load/store之间;DSB强调的是同类或不同类事物的先后完成。

Data Memory Barrier (DMB) ensures that all explicit memory accesses that appear in program order before the DMB instruction are observed

before any explicit memory accesses that appear in program order after the DMB instruction.

数据内存屏障(DMB)确保DMB指令之前的所有显式内存访问在DMB指令开始之后的任何显式内存访问之前被观察到。且DMB指令不影响处理上执行的任何其他指令的顺序。

Data Synchronization Barrier (DSB),No instruction in program order after this instruction executes until this instruction completes.

数据同步屏障(DSB)完成后,其后面的指令才可执行。可见DSB影响了其他指令的执行。

Instruction Synchronization Barrier (ISB) flushes the pipeline in the processor, so that all instructions following the ISB are fetched from cache or memory,

after the instruction has been completed.

指令同步屏障(ISB)冲刷处理器中的流水线,以便在ISB完成后,从缓存或内存中提取ISB之后的所有指令。可见ISB严重影响后续指令的执行。

3、linux内核实现

arch/arm/include/asm/barrier.h/*isb,dsb,dmb汇编指令*/
#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")/*barrier:编译优化屏障,阻止编译器为了性能优化而进行指令重排*/
#define barrier() __asm__ __volatile__("": : :"memory")/*内存屏障(包括读和写),用于SMP和UP*/
#define mb()		do { dsb(); outer_sync(); } while (0)
/*读内存屏障,用于SMP和UP*/
#define rmb()		dsb()
/*写内存屏障,用于SMP和UP*/
#define wmb()		do { dsb(st); outer_sync(); } while (0)/*osh:outer shareable domain*/
#define dma_rmb()	dmb(osh)
#define dma_wmb()	dmb(oshst)/*用于SMP场合的内存屏障。*/
/*ish:inner shareable domain,在ish范围内客观测到结果*/
#define smp_mb()	dmb(ish)
/*用于SMP场合的读内存屏障*/
#define smp_rmb()	smp_mb()
/*用于SMP场合的写内存屏障*/
/*waits only for stores to complete, and only to the inner shareable domain.*/
#define smp_wmb()	dmb(ishst)

http://www.lryc.cn/news/445007.html

相关文章:

  • 【人工智能】Transformers之Pipeline(十九):文生文(text2text-generation)
  • 如何使用ssm实现基于VUE的儿童教育网站的设计与实现+vue
  • MODBUS TCP 转 CANOpen
  • vue2+elementUI实现handleSelectionChange批量删除-前后端
  • LLMs之OCR:llm_aided_ocr(基于LLM辅助的OCR项目)的简介、安装和使用方法、案例应用之详细攻略
  • 低代码平台后端搭建-阶段完结
  • 暑假考研集训营游记
  • C#中的报文(Message)
  • Python知识点:如何使用Python与Java进行互操作(Jython)
  • ffmpeg解封装解码
  • golang学习笔记10-循环结构
  • Java高级编程——泛型(泛型类、泛型接口、泛型方法,完成详解,并附有案例+代码)
  • GPU硬件如何实现光栅化?
  • Python写入文件内容:从入门到精通
  • 相亲交易系统源码详解与开发指南
  • Golang | Leetcode Golang题解之第413题等差数列划分
  • 汽车总线之----FlexRay总线
  • 前端代替后端做分页操作
  • L3 逻辑回归
  • Flink系列知识之:Checkpoint原理
  • 智算中心动环监控:构建高效、安全的数字基础设施@卓振思众
  • PyTorch VGG16手写数字识别教程
  • 安卓13删除下拉栏中的设置按钮 android13删除设置按钮
  • FDA辅料数据库在线免费查询-药用辅料
  • git pull 报错 refusing to merge unrelated histories
  • STM32G431RBT6(蓝桥杯)串口(发送)
  • 使用 typed-rest-client 进行 REST API 调用
  • 在Ubuntu 14.04上安装Solr的方法
  • LabVIEW提高开发效率技巧----使用LabVIEW工具
  • Pyspark dataframe基本内置方法(4)