linux ARM64 处理器内存屏障

一、内存类型:

ARMv8架构将系统中所有的内存,按照它们的特性,划分成两种,即普通内存和设备内存。并且它们是互斥的,也就是说系统中的某段内存要么是普通内存,要么是设备内存,不能都是。

1)普通内存(Normal Memory)

普通内存的特性是,在没有别的写入的情况下,每次读取出来的值都是一样的。针对普通内存,Arm处理器会采用比较激进的优化方式,从而导致指令重排序的问题。

普通内存可以被指定为支持缓存(Cached)或不支持缓存(Non-Cached)。如果两个模块之间不支持数据一致性协议,那么它们之间的共享内存一定是不支持缓存的。

2)设备内存(Device Memory)

设备内存一般是对外部设备的一段内存映射,在没有写入的情况下,可能每次读取出来的值都不一样。也有可能写入这段内存会产生别的边际效应,如触发一个中断。

二、共享域

为了支持数据一致性协议,需要增加硬件很多开销,会降低系统的性能,同时也会增加系统的功耗。但是,很多时候并不需要系统中的所有模块之间都保持数据一致性,而只需要在系统中的某些模块之间保证数据一致性就行了。因此,需要对系统中的所有模块,根据数据一致性的要求,做出更细粒度的划分。

ARMv8架构将这种划分称作为域(Domain),并且一共划分成了四类:

1)非共享(Non-shareable)域

处于这个域中的内存只由当前CPU核访问,既然只能自己访问,那当然不用考虑跟系统中的其它模块,如其它CPU核或其它设备之间的数据同步问题。所以,如果一个内存区域是非共享的,系统中没有任何硬件会保证其缓存一致性。如果一不小心共享出去了,别的CPU核可以访问了,那必须由软件自己来保证其一致性。

2)内部共享(Inner Shareable)域

处于这个域中的内存可以由系统中的多个模块同时访问,并且系统硬件保证对于这段内存,对于处于同一个内部共享域中的所有模块,保证缓存一致性。

一个系统中可以同时存在多个内部共享域,对一个内部共享域做出的操作不会影响另外一个内部共享域。

3)外部共享(Outer Shareable)域

处于这个域中的内存也可以由系统中的多个模块同时访问,并且系统硬件保证对于这段内存,对于处于同一个外部共享域中的所有模块,保证缓存一致性。外部共享域可以包含一个或多个内部共享域,但是一个内部共享域只能属于一个外部共享域,不能被多个外部共享域共享。

对一个外部共享域做出的操作会影响到其包含的所有的内部共享域。

4)全系统共享(Full System)域

这个很好理解,表示对内存的修改可以被系统中的所有模块都感知到。

在一个具体的系统中,不同域的划分是由硬件平台设计者决定的,不由软件控制。并且,Arm的文档中也没有提及具体要怎么划分。但有一些指导原则,一般在一个操作系统中可以看到的所有CPU核要分配在一个内部域里面,如下图所示:

这些域的划分只是为了更细粒度的管理内存的缓存一致性,理论上所有内存都放到全系统共享域中,从功能上说也可以,但会影响性能。

可缓存性和共享性一定是对普通内存才有的概念。设备内存一定是不支持缓存的,且是外部共享的。

三、屏障

不同处理器提供的内存屏障指令不同, ARM64 处理器提供了 3 种内存屏障。

(1)指令同步屏障( Instruction Synchronization Barrier, ISB),指令是 isb。

(2)数据内存屏障( Data Memory Barrier, DMB),指令是 dmb。

(3)数据同步屏障( Data Synchronization Barrier, DSB),指令是 dsb。

指令同步屏障指令冲刷流水线,在屏障指令执行完毕后重新取程序中屏障指令后面的所有指令,以便使用最新的内存管理单元配置检查权限和访问。屏障指令确保以前执行的改变上下文的操作(包括缓存维护指令、页表缓存维护指令或修改系统控制寄存器)在屏障指令执行完的时候已经完成。

数据内存屏障保证屏障前面的内存访问和屏障后面的内存访问的相对顺序,屏障前面的内存访问必须在屏障后面的内存访问之前被观察到,但是不保证屏障前面的内存访问完成。

数据同步屏障保证屏障前面的内存访问、缓存维护指令和页表缓存维护指令在屏障完成之前已经完成,屏障后面的任何指令在屏障完成之后才能开始执行,是比数据内存屏障更强的屏障。

DMB和DSB指令都需要带一个参数,这个参数指明了数据屏障指令的作用范围和针对的共享域。共享域前面说过了,一共有四种。作用范围表示数据屏障指令具体对哪些存储器访问操作起作用,ARMv8共定义了三种,分别是:

1.  Load - Load, Load - Store:表示内存屏障保证其之前的所有加载操作一定在其之前完成,其之后的所有加载和存储操作一定在其之后才开始,但是其之前的存储操作有可能会在其之后才执行。

2.  Store - Store:表示内存屏障保证其之前的所有存储操作一定在其之前完成,而其之后的存储操作一定在其之后才能开始,但是对于加载操作没有任何限制。

3.  Any - Any:表示内存屏障保证其之前的所有加载和存储操作一定在其之前完成,而其后的所有加载和存储操作一定在其之后才能开始。

注意,ARMv8不提供所谓的Store-Load型的顺序保证,如果真的需要这种保证,只能使用Any-Any型的。关于DMB和DSB指令的参数,可以总结为如下表格:

参数

作用范围

共享域

OSHLD

Load - Load, Load - Store

外部共享域

OSHST

Store - Store

外部共享域

OSH

Any - Any

外部共享域

NSHLD

Load - Load, Load - Store

非共享域

NSHST

Store - Store

非共享域

NSH

Any - Any

非共享域

ISHLD

Load - Load, Load - Store

内部共享域

ISHST

Store - Store

内部共享域

ISH

Any - Any

内部共享域

LD

Load - Load, Load - Store

全系统共享域

ST

Store - Store

全系统共享域

SY

Any - Any

全系统共享域

ARM64 架构定义的内存屏障宏如下。

(1) #define mb() asm volatile("dsb sy” : : : "memory")

使用数据同步屏障指令,保证屏障前面的读写操作在屏障完成之前已经完成,使整个系统看见。

(2) #define wmb() asm volatile("dsb st” : : : "memory")

使用数据同步屏障指令,保证屏障前面的写操作在屏障完成之前已经完成,使整个系统看见。

(3) #define rmb() asm volatile("dsb ld” : : : "memory")

使用数据同步屏障指令,保证屏障前面的读操作在屏障完成之前已经完成,使整个系统看见。

(4) #define read_barrier_depends() do { } while (0)

(5) #define smp_mb() asm volatile("dmb ish” : : : "memory")

使用数据内存屏障指令, 保证屏障前面的读写操作和屏障后面的读写操作的相对顺序,使内部共享域(包括所有处理器)看见。

(6) #define smp_wmb() asm volatile("dmb ishst” : : : "memory")

使用数据内存屏障指令,保证屏障前面的写操作和屏障后面的写操作的相对顺序,使内部共享域看见。

(7) #define smp_rmb() asm volatile("dmb ishld” : : : "memory")

使用数据内存屏障指令,保证屏障前面的读操作和屏障后面的读写操作的相对顺序,使内部共享域看见。

(8) #define smp_read_barrier_depends() do { } while (0)

(9) #define dma_wmb() asm volatile("dmb oshst” : : : "memory")

使用数据内存屏障指令,保证屏障前面的写操作和屏障后面的写操作的相对顺序,使外部共享域(包括所有处理器和外围设备)看见。

(10) #define dma_rmb() asm volatile("dmb oshld” : : : "memory")

使用数据内存屏障指令,保证屏障前面的读操作和屏障后面的读写操作的相对顺序,使外部共享域看见。

ARM64 还提供了带有隐含单向屏障的加载和存储指令。

(1)加载获取指令 ldar。

加载获取指令后面并且匹配目标地址的共享域的所有加载存储操作必须在加载获取指令之后被观察到。所以,可以看出来,这条指令是个单向屏障,只挡住了后面出现的所有内存操作指令,但是没有挡住这条指令之前的所有内存操作指令。

(2)存储释放指令 stlr。

存储释放指令前面并且匹配目标地址的共享域的所有加载存储操作必须在存储释放指令之前被观察到,并且存储释放指令生成的存储操作在该指令执行完之后可以被观察到。所以,这条指令也是一个单向屏障,只挡住了前面出现的所有内存操作指令,但是没有挡住这条指令之后的所有内存操作指令。

单向屏障的作用范围可以总结为下面这张图:

ARM64 还提供了上面两条指令的独占版本: ldaxr 和 stlxr。

ARM64 架构的内核使用加载获取指令实现了加载获取函数 smp_load_acquire(p)和 smp_cond_load_acquire(ptr, cond_expr),使用存储释放指令实现了存储释放函数 smp_store_release(p, v)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/259746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动力电池系统介绍(十四)——热管理系统

动力电池系统介绍(十四) 一、梗概二、座舱热管理(汽车空调)2.1 空调制冷2.2 空调制热2.2.1 传统燃油汽车空调制热2.2.2 新能源汽车空调制热 三、动力系统热管理3.1 燃油车发动机热管理3.1.1 冷却系统3.1.2 润滑系统3.1.3 进排气系…

C++ Lambda表达式基础用法

语法 C11标准lambda表达式的语法非常简单,定义如下,并且语法规定lambda表达式如果存在说明符,那么形参列表不能省略。标准还规定能捕获的变量必须是一个自动存储类型。简单来说就是非静态的局部变量、非全局变量。 定义:[ captu…

纳米流体传热与计算机模拟

纳米流体传热与计算机模拟 一、引言 纳米流体传热是一个研究领域,主要关注纳米尺度下流体的传热特性和机制。由于纳米流体的尺寸较小,其传热行为与传统尺度下的流体有很大不同。近年来,随着计算机技术的飞速发展,计算机模拟成为…

TensorFlow(2):Windows安装TensorFlow

1 安装python环境 这一步请自行安装,这边不做介绍。 2 安装anaconda 下载路径:Index of /,用户自行选择自己的需要的版本。 3 环境配置 3.1 anaconda环境配置 找到设置,点击系统->系统信息->高级系统设置->环境变量…

Github 2023-12-19开源项目日报 Top10

根据Github Trendings的统计,今日(2023-12-19统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4Rust项目2非开发语言项目2C#项目1TypeScript项目1 Avalonia: 跨平台UI框架和Avalonia XPF 创建周…

高高。。。。

重点:存储系统/分布式系统 得到数据: 数据模型计算(简单系统)实现一个操作系统CPU(成本高)仿真实验 文章类型: 国际会议 10-15slices期刊论文 做OS研究为其他方面提供支持 一 Advanced OS …

鸿蒙开发运用ArkUI基础-实操显式动画

利用ArkUI组件不仅可以实现属性变化引起的属性动画,也可以实现父组件状态变化引起子组件产生动画效果,这种动画为显式动画。效果如图所示: 代码结构解读 ├──entry/src/main/ets // 代码区 │ ├──common │ │ └──…

css 美化滚动条

当div内容溢出容器定义的高度时,滚动条显示,并美化默认的滚动条样式 div 容器 <divclass"content">内容 </div>css 样式 /* 问话区域 滚动条 */ .content {overflow: auto;height: 662px;padding: 25px;scrollbar-width: thin; /* 设置滚动条宽度 */bo…

四川云汇优想教育咨询有限公司电商服务靠谱吗

随着抖音电商的兴起&#xff0c;越来越多的商家开始关注这一领域。四川云汇优想教育咨询有限公司作为一家专注于电商服务的企业&#xff0c;也受到了广泛的关注。那么&#xff0c;四川云汇优想教育咨询有限公司的抖音电商服务靠谱吗&#xff1f;下面我们将从多个方面进行深入剖…

大模型赋能“AI+电商”,景联文科技提供高质量电商场景数据

据新闻报道&#xff0c;阿里巴巴旗下淘天集团和国际数字商业集团都已建立完整的AI团队。 淘天集团已经推出模特图智能生成、官方客服机器人、万相台无界版等AI工具&#xff0c;训练出了自己的大模型产品 “星辰”&#xff1b; 阿里国际商业集团已成立AI Business&#xff0c;…

在线教育(内部)培训系统搭建,提供高效便捷的学习体验

我国一直是教育大国&#xff0c;不管是国民义务教育&#xff0c;还是学历提升、职业证书等&#xff0c;我国教育行业一直处于兴盛不衰的地步。 随着互联网信息化的发展&#xff0c;在线教育培训系统逐渐在教育行业得到重视。根据数据显示&#xff0c;我国在线教育市场规模将达…

拼图游戏

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import jav…

探索泰勒级数在机器学习中的作用:从函数逼近到模型优化

一、介绍 泰勒级数是数学中的一个基本概念&#xff0c;在机器学习领域有着重要的应用。本文将探讨泰勒级数的基础知识、它在机器学习中的相关性以及一些具体应用。 揭开复杂性&#xff1a;利用泰勒级数增强机器学习应用的理解和效率。 二、理解泰勒级数 在数学中&#xff0c;泰…

Leetcode—128.最长连续序列【中等】

2023每日刷题&#xff08;六十四&#xff09; Leetcode—128.最长连续序列 实现代码 class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int> s;for(auto num: nums) {s.insert(num);}int longestNum 0;for(auto num: s) …

Python Opencv实践 - 手部跟踪

使用mediapipe库做手部的实时跟踪&#xff0c;关于mediapipe的介绍,请自行百度。 mediapipe做手部检测的资料&#xff0c;可以参考这里&#xff1a; MediaPipe Hands: On-device Real-time Hand Tracking 论文阅读笔记 - 知乎论文地址&#xff1a; https://arxiv.org/abs/2006…

Shell三剑客:awk(简介)

一、前言 AWK 是一种编程语言&#xff0c;用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件&#xff0c;或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能&#xff0c;是linux/unix下的一个强大编程工具。它在命令行中使用&a…

3 - Electron app BrowserWindow对象-关于窗口

优雅的打开应用~ 当加载缓慢&#xff0c;打开应用的一瞬间会出现白屏&#xff0c;以下方法可以解决 const mainWindow new BrowserWindow({ show: false }) mainWindow.once(ready-to-show, () > {mainWindow.show() }) 设置背景颜色 const win new BrowserWindow({ b…

VueCron使用方法

1&#xff09;什么是vueCron Vue Cron 是基于 Vue.js 的定时任务管理组件&#xff0c;它提供了一种简单易用的方式来设定和管理定时任务。Vue Cron 提供了一个类似于 Linux crontab 的界面&#xff0c;用户可以通过它来创建、编辑和删除定时任务。 2&#xff09;安装依赖及应…

FreeCodeCamp--数千免费编程入门教程,非盈利性网站,质量高且支持中文

在浏览话题“Github上获得Star最多的项目”时&#xff0c;看到了FreeCodeCamp&#xff0c;顾名思义--免费编程营地&#xff0c;于是就做了些调研&#xff0c;了解了下这是个什么项目 这是一个致力于推动编程教育的非营利性组织&#xff0c;团队由来自世界各地的杰出的技术开发…

如何将图片转为PDF

问题描述&#xff1a;如何将图片转为PDF&#xff0c;有时需要将纸质文档扫描成PDF&#xff0c;然后上传到网上。 解决办法&#xff1a;平时使用的方法是将图片插入到word文件中&#xff0c;然后将图片设置为浮于文字下方&#xff0c;然后调整图片的大小&#xff0c;铺满整个wo…