linux ARM64 处理器内存屏障

2023-12-20

一、内存类型:

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)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux ARM64 处理器内存屏障 的相关文章

  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • 如何从linux命令行运行.exe可执行文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Windows 中有一个 abc exe 可执行文件 我可以使用 DOS 命令提示来执行此应用程序 并为其提供一些运行时变量 我想从
  • Scrapy FakeUserAgentError:获取浏览器时发生错误

    我使用 Scrapy FakeUserAgent 并在我的 Linux 服务器上不断收到此错误 Traceback most recent call last File usr local lib64 python2 7 site pack
  • 如何查明 Ubuntu 上安装了哪个版本的 GTK+?

    我需要确定 Ubuntu 上安装了哪个版本的 GTK 男人似乎不帮忙 这个建议 https stackoverflow com a 126145 会告诉您安装了哪个 2 0 的次要版本 不同的主要版本将具有不同的包名称 因为它们可以在系统上
  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b
  • numpy 未定义符号:PyFPE_jbuf

    我正在尝试使用一百万首歌曲数据集 为此我必须安装 python 表 numpy cython hdf5 numexpr 等 昨天我设法安装了我需要的所有内容 在使用 hdf5 遇到一些麻烦之后 我下载了预编译的二进制包并将它们保存在我的 b
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • Linux 桌面快捷方式和安装图标

    我需要添加什么到我的 spec文件来创建桌面快捷方式并在安装过程中为快捷方式分配一个图标 rpm 如果需要脚本 一个示例将非常有帮助 您在 Linux 下使用 desktop 文件作为图标 图标放置的位置取决于您使用的发行版和桌面环境 由于
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte

随机推荐

  • JMeter 性能测试基本过程及示例

    jmeter 为性能测试提供了一下特色 jmeter 可以对测试静态资源 例如 js html 等 以及动态资源 例如 php jsp ajax 等等 进行性能测试 jmeter 可以挖掘出系统最大能处理的并发用户数 jmeter 提供了一
  • 【已解决】Redis序列化反序列化不一致 - String类型值多了双引号问题

    在项目中使用spring 的RedisTemplate从redis中获取数据的时候 发现字符串的value多了双引号 如下图所示 产生的原因可以分一下几个方面 一 采用的序列化对象不同 多服务之间调用时候 序列化服务A 向redis中写数据
  • 微服务常见的配置中心简介

    微服务架构中 常见的配置中心包括以下几种 Spring Cloud Config Spring Cloud Config是官方推荐的配置中心解决方案 它支持将配置文件存储在Git SVN等版本控制系统中 通过提供RESTful API 各个
  • 漏洞复现-亿赛通任意文件读取漏洞(附漏洞检测脚本)

    免责声明 文章中涉及的漏洞均已修复 敏感信息 均已做打码处理 文章仅做 经验分享 用途 切勿当真 未授权的攻击属于非法行为 文章中 敏感信息 均已做多层打马处理 传播 利用本文章所提供的信息而造成的任何直接或者间接的后果及损失 均由使用者本
  • 行业追踪,2023-12-20

    自动复盘 2023 12 20 凡所有相 皆是虚妄 若见诸相非相 即见如来 k 线图是最好的老师 每天持续发布板块的rps排名 追踪板块 板块来开仓 板块去清仓 丢弃自以为是的想法 板块去留让市场来告诉你 跟踪板块总结 成交额超过 100
  • 加速Scrum敏捷转型的必选培训机构

    针对敏捷转型培训 有一些知名的培训公司提供专业的敏捷培训课程和认证 以下是几家备受认可的敏捷转型培训公司 Leangoo领歌 Leangoo领歌是一款 永久免费的专业的敏捷开发管理工具 提供端到端敏捷研发管理解决方案 包括 小型团队敏捷开发
  • 【开题报告】基于SpringBoot的工资管理系统

    1 研究背景 基于SpringBoot的工资管理系统的选题背景主要可以从以下几个方面来考虑 1 企业运营管理需求 在现代企业中 薪资管理是人力资源管理的重要组成部分 直接影响到员工的工作积极性和企业的运营成本 随着企业规模的扩大和业务复杂性
  • Docker:容器化技术的革命者

    Docker介绍 随着云计算和虚拟化技术的不断发展 容器化技术逐渐成为了一种主流的部署和运行应用的方式 而在这个领域中 Docker无疑是最具影响力和最受欢迎的容器化技术之一 本文将介绍Docker的基本概念 优势以及应用场景 一 Dock
  • 基于SpringBoot的网上订餐系统的设计与实现

    一 选题背景 国内研究背景 互联网的发展为人们的生产 生活带来了许多便利 传统餐饮业和产业服务采用互联网技术 让整个餐饮业在转型过程中少走了弯路 取得了更好的发展 1 发达国家的 O2O 模式已经非常成熟 OpenTable 是美国目前市场
  • Temu诉讼为公关手段?出海警惕恶性竞争!

    在国内流量见顶 人口红利接近尾声时 国内企业出海谋发展 已是必然 因此 以Temu与Shein为代表的跨境电商平台 也成为这个赛道的新生力量 正在带领我国企业奔向星辰大海 不过 虽然各大巨头角逐的市场更为宽广 但是面临的市场竞争同样激烈 例
  • 如何有效获取APP新增用户

    在提升APP用户获取效果方面 有几个关键策略可以考虑 市场定位与目标用户明确 在推广过程中 确保清晰地了解你的目标用户是谁 以便有针对性地开展推广活动 对用户的需求和偏好有深入了解 可以更好地制定吸引用户的策略 引人入胜的营销策略 设计有吸
  • 【知识分享】Java实现“羊了个羊”的思路和代码

    羊了个羊 是一款近期流行的消除类游戏 其核心玩法是通过交换两张卡片来使三张相同的卡片连成一条线进行消除 以下是一个简单的Java实现思路和代码示例 首先 我们需要定义一个表示卡片的类 public class Card private St
  • 使用ASPOSE在一个word文件的自定义标记处插入另一个word

    package mycmf office import java io File import java io FileInputStream import java io IOException import java io InputS
  • 业界翘楚!百望云斩获钛媒体“年度最佳企业服务品牌”大奖

    近日 由钛媒体集团主办的2023 T EDGE全球创新大会暨EDGE AWARDS创新评选在北京隆重举办 会上 钛媒体重磅发布了2023 EDGE AWARDS全球创新评选榜单 百望云凭借 据全球知名咨询公司弗若斯特沙利文报告 百望云在20
  • 基于Python+django短视频推荐系统

    1 1 研究背景和意义 社会经济水平的发展带动了网络技术的发展 网上的信息越来越多 在如今人们基本离不开互联网 人们在网上浏览各种信息 眼花缭乱 很难从这种背景下找到自己感兴趣的信息 既浪费人们的大量时间 也没有任何体验感 信息也越来越难展
  • linux 内核同步互斥技术之cache 伪共享和隐含内存屏障

    隐含内存屏障 内核的有些函数隐含内存屏障 1 获取和释放函数 2 中断禁止函数 1 获取和释放函数 获取 acquire 函数包括如下 1 获取锁的函数 锁包括自旋锁 读写自旋锁 互斥锁 信号量和读写信号量 2 smp load acqui
  • 快速能访问服务器的文件

    1 背景 访问ubuntu上的文件 2 方法 python3 m http server 8081 directory home NAS 共享访问协议 NFS SMB FTP WebDAV 各有何优势 http 1 Ubuntu 搭建文件服
  • ubuntu 打开所有端口

    1 打开所有端口 ubuntu开启所有端口 iptables P INPUT ACCEPT iptables P FORWARD ACCEPT iptables P OUTPUT ACCEPT iptables F iptables sav
  • .netCHARTING 10.6 .NET 8.0 Chart Support --Crack

    netCHARTING enables your web site to display massive amounts of dynamically generated data quickly and easily through a
  • linux ARM64 处理器内存屏障

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