linux ARM64 处理器内存屏障

2023-12-21

一、内存类型:

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 处理器内存屏障 的相关文章

  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • arm-linux-gnueabi 编译器选项

    我在用 ARM Linux gnueabi gcc在 Linux 中为 ARM 处理器编译 C 程序 但是 我不确定它编译的默认 ARM 模式是什么 例如 对于 C 代码 test c unsigned int main return 0x
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • ansible 重新启动 2.1.1.0 失败

    我一直在尝试创建一个非常简单的 Ansible 剧本 它将重新启动服务器并等待它回来 我过去在 Ansible 1 9 上有一个可以运行的 但我最近升级到 2 1 1 0 并且失败了 我正在重新启动的主机名为 idm IP 为 192 16
  • 在 Mac OS X 上构建 Linux 内核

    我正在做一个修改Linux内核的项目 我有一台桌面 Linux 机器 在上面构建内核没有问题 不过 我要去旅行 我想在途中工作 我只有一台 MacBook 当我尝试构建 Linux 内核时 它抱怨说elf h was not found 我
  • 拆分字符串以仅获取前 5 个字符

    我想去那个地点 var log src ap kernelmodule 10 001 100 但看起来我的代码必须处理 ap kernelmodule 10 002 100 ap kernelmodule 10 003 101 等 我想使用
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • GLIBCXX_3.4.26 未找到在 BeagleBone 上运行交叉编译的程序

    我有以下程序 include
  • 应用程序无缘无故地被杀死。怀疑 BSS 高。如何调试呢?

    我已经在CentOs6 6中成功运行我的应用程序 最近 硬件 主板和内存 更新了 我的应用程序现在毫无理由地被杀死 root localhost PktBlaster PktBlaster Killed 文件和 ldd 输出 root lo
  • nginx 上的多个网站和可用网站

    通过 nginx 的基本安装 您的sites available文件夹只有一个文件 default 怎么样sites available文件夹的工作原理以及如何使用它来托管多个 单独的 网站 只是为了添加另一种方法 您可以为您托管的每个虚拟
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 我可以从命令行打印 html 文件(带有图像、css)吗?

    我想从脚本中打印带有图像的样式化 html 页面 谁能建议一个开源解决方案 我使用的是 Linux Ubuntu 8 04 但也对其他操作系统的解决方案感兴趣 你可以给html2ps http user it uu se jan html2
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • nslookup 报告“无法解析 '(null)': 名称无法解析”,尽管它成功解析了 DNS 名称

    我在 ubuntu 上 并且正在运行 docker 默认桥接网络 我有 Zookeeper kafka 的容器化版本 以及我编写的与 kafka 对话的应用程序 I do a docker exec it
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • 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 普通内存的特性是