ARMv8 同步和信号量(读写一致性问题):Load-Exclusive/Store-Exclusive指令详解

news2024/11/23 18:24:32

 

目录

一,Local Monitor 与 Global Monitor

1,Local Monitor

2,Global Monitor

 二,Exclusive 指令的简单使用

三,Exclusive 示例程序

1,原子自加1程序

 2,原子锁程序

四, 多处理器多线程中Exclusive指令执行解析


在上篇文章中介绍了ARMv8中同步与信号量的基本原理:

ARMv8 同步和信号量(Synchronization and semaphores)简介_SOC罗三炮的博客-CSDN博客

接下来本文将继续围绕这个话题,详细介绍Exclusive相关指令:Load-Exclusive/Store-Exclusive的具体使用。

一,Local Monitor 与 Global Monitor

在ARMv8 同步和信号量(Synchronization and semaphores)简介_SOC罗三炮的博客-CSDN博客 一文中有对local monitor和global monitor做详细描述。

1,Local Monitor

如果内存被标记为Non-shareable内存,说明该内存不可共享的,只能被单个处理器访问。所以对这种内存的读写一致性问题,只需要Local monitor维护即可。Local monitor只在处理器内部维护exclusive状态,由于不涉及多处理器的exclusive状态共享,所以不需要对真正的内存进行标记。在硬件实现上,可以通过对内存地址进行标记exclusive状态,来实现单个处理器的读写一致性。也可以通过追踪exclusive 指令(Load-Exclusive/Store-Exclusive)来维护单处理器中多线程读写一致性。

2,Global Monitor

对于shareable 内存,既可共享内存而言,该类型内存可以被多个处理器同时访问,此时需要使用Global Monitor来维护读写一致性,通过对共享内存的物理内存标记为独占式访问:定义一个mutex信号量,来保证多处理器并发时的多读单写。

根据ARMv8手册描述:global monitor可以存在于处理器中,也可以作为一个二级的monitor存在于内存接口中。在具体的设计实现中,Local monitor和Global Monitor甚至可以合并成一个独立单元,但是既提供local  monitor的功能和global monitor的功能。

下图是Exclusive的一种实现架构:Local monitor位于各个处理器中,多个处理器共用一个global monitor:

 二,Exclusive 指令的简单使用

在AArch32中,使用的Exclusive 指令是LDREX和STREX:

LDREX R1, [R0]
STREX R2, R1, [R0]

在AArch64中,使用的Exclusive 指令是LDXR & STXR:

ldxr w0, [x9]
stxr w8, w0, [x9] 

 下面以LDREX和STREX为例,介绍两个指令的简单使用:

LDREX R1, [R0] 指令将加载 R0所指向内存地址的一个word(4 bytes)数据,加载到R1中。同时会初始化Exclusive monitor的exclusive 状态,并将R0所指向的内存区域(一个granule 大小)标记为Exclusive access。

STREX R2, R1, [R0] 是一个有条件的 store指令,它是否成功执行,取决于Exclusive monitor,如果Exclusive monitor通过状态机发现存在Store-Exclusive指令成功执行的条件:

  • Store操作将执行:R1中的值将会被更新到R0所指向的内存位置
  • monitor中的Exclusive 状态将会被清除,之前被标记为Exclusive access的内存区域也会被清除标记
  • 状态寄存器R2中的值将会被设置为0,表明该STREX指令执行成功。

如果不具备Store-Exclusive指令成功执行的条件,Store操作将不会进行,状态寄存器R2中的值将会被设置为1,表明该STREX指令执行失败。

此外,LDREX和STREX是对内存中的一个字(Word,32 bit)进行独占访问的指令。如果想独占访问的内存区域不是一个字,还有其它的指令:

  1. LDREXB和STREXB:对内存中的一个字节(Byte,8 bit)进行独占访问;
  2. LDREXH和STREXH:中的一个半字(Half Word,16 bit)进行独占访问;
  3. LDREXD和STREXD:中的一个双字(Double Word,64 bit)进行独占访问。

它们必须配对使用,不能混用。

三,Exclusive 示例程序

1,原子自加1程序

下面的例子给出了使用 LDXR & STXR 实现原子加一的过程:

; extern int atom_add(int *val);
_atom_add:
mov x9, x0 ; 备份 x0,为了失败时恢复,x9=x0=*val
ldxr w0, [x9] ; 从val所在的内存中读取一个 int,并标记 Exclusive
add w0, w0, #1 ; w0=w0+1
stxr w8, w0, [x9] ; 尝试写回 val 位置,写入结果保存在 w8
cbz w8, atom_add_done ; 如果 w8 为 0 说明成功,跳到程序结束
mov x0, x9 ; 恢复备份的 x0,重新执行 atom_add
b _atom_add
atom_add_done:
ret

另一个自加程序 (存在于 libkern 提供的 OSAtomicAdd32 函数):

;int32_t OSAtomicAdd32(int32_t __theAmount, volatile int32_t *__theValue);
ldxr    w8, [x1]      ;将__theValue的值加载到w8,同时标记Exclusive access状态
add     w8, w8, w0     ; w8=w8+w0, w0=__theAmount
stxr    w9, w8, [x1]     ;将w8写回到*__theValue, 结果保存到w9
cbnz    w9, _OSAtomicAdd32 ;判断w9是否为0,不为0则跳到函数头,重新执行函数
mov     x0, x8        ;成功则将w8作为返回值返回
ret     lr

 2,原子锁程序

关于此原子锁程序的解析,参考原文:ARMv8之exclusive操作(二)exclusive操作例子 | 骏的世界

; void lock(lock_t *ptr)
lock:
    ; is it locked?
    LDXR   W1, [X0]        ; Load current value of lock
    CMP       W1, #LOCKED  ; Compare with "LOCKED"
    B.EQ   lock            ; If LOCKED, try again
 
    ; Attempt to lock
    MOV       W1, #LOCKDED
    STXR   W2, W1, [X0]    ; Attempt to lock
    CBNZ   W2, lock        ; If STXR failed, try again
    DMB    SY              ; Ensures acesses to the resource are not made
                           ; before the lock is acquired
    RET

 

四, 多处理器多线程中Exclusive指令执行解析

在文章ARMv8之exclusive操作(二)exclusive操作例子 | 骏的世界中,解析了两个线程进行抢锁的过程。扩展到多线程,多个CPU也是一样的原理:对同个地址进行读写操作时,同一时间只会有一个线程能成功完成读写操作。

下面将举一个多处理器多线程的例子,来分析ARMv8中独占式访问的原理:

如下图所示,某系统中有两个CPU,CPU0里有两个线程:Thread 1执行程序1,Thread 2执行程序2,。CPU1中有一个线程:线程3中执行程序2。三个线程中的程序都对同一个地址A进行访问。

它们的执行顺序如下:

  1. CPU1的thread 3最先执行LDREX,锁定地址A开始的内存区域为exclusive access,同时更新CPU1的local monitor和global monitor的状态为Exclusive 状态。
  2. 然后CPU0的Thread1也执行LDREX,它也会更新CPU0 的local monitor和global monitor的状态为Exclusive状态。此时,在global monitor的视角中,CPU0和CPU1都对以地址A开始的一段内存做了Exclusive acces的标记。
  3. 接着,CPU0的Thread2也执行到了LDREX,此时它会发现CPU0的local monitor已经对该段内存做了独占标记,同时global monitor上CPU0也对该内存做了独占标记。但这并不会影响该指令的执行。
  4. 接下来,CPU0的Thread1首先执行STREX指令,尝试往地址A写入新的值。此时发现CPU0的local monitor对该段内存进行了独占访问标记,并且global monitor中也有CPU 0对该内存的独占标记,所以STREX指令将成功执行。同时会清除CPU0的local monitor以及global monitor中所有处理器对该段内存的独占标记。
  5. 接下来CPU1的Thread3也执行到了STREX,但是此时只有CPU1的local monitor对该段内存有独占标记,global monitor中没有CPU1的独占标记。所以更新失败,STREX指令执行失败。
  6. 同理,CPU0的Thread2执行STREX时也将失败,它会发现不管是local monitor还是global monitor都没有对该段内存的独占标记。
  7. 如果程序2是上文提到的原子自加程序,在执行STREX指令失败后,将会重新进行LDREX,此时,三个线程执行完成的顺序为:Thread1 - Tread3 - Tread2。

ARM的exclusive独占式访问的机制的核心在于:

在同一时间内,允许多个观察者对同一段内存进行读取,标记为独占式访问,但是只允许其中一个观察者能够对该内存进行成功写入,按照先写先得原则,最先执行完LDREX/STREX指令对的观察者(最先完成对该内存的更新)可以成功,其他的都会失败

这样就可以维护多个观察者的读写一致性问题。实际的使用中,可以重新用LDREX读取该段内存中保存的最新值,再处理一次,再尝试保存,直到成功为止。

参考文章:

iOS汇编教程(七)ARM Exclusive - 互斥锁与读写一致性的底层实现原理 - 掘金在多线程编程中,我们常常使用互斥锁来保证全局变量的线程安全,例如 pthread 中的 pthread_mutex,mach 中的 semaphore。他们通过 lock & unlock 或是 up & down 的方式来维护资源的状态,保证只有特定个数的线程能获得特定个数的…https://juejin.cn/post/6844903970536685576ARM平台下独占访问指令LDREX和STREX的原理与使用详解_adaptiver的博客-CSDN博客_ldrexLDREX Rx, [Ry]读取寄存器Ry指向的4字节内存值,将其保存到Rx寄存器中,同时标记对Ry指向内存区域的独占访问。STREX Rx, Ry, [Rz]如果执行这条指令的时候发现已经被标记为独占访问了,则将寄存器Ry中的值更新到寄存器Rz指向的内存,并将寄存器Rx设置成0。指令执行成功后,会将独占访问标记位清除。而如果执行这条指令的时候发现没有设置独占标记,https://blog.csdn.net/adaptiver/article/details/72392825ARMv8之exclusive操作(二)exclusive操作例子 | 骏的世界http://www.lujun.org.cn/?p=4142

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法设计与智能计算 || 专题一: 算法基础

专题一: 算法基础 文章目录专题一: 算法基础1. 算法的定义及特点1.1 算法的基本特征1.2 算法的基本要素1.3 算法的评定2 算法常见执行方法2.1 判断语句2.2 循环语句2.3 综合运用3. 计算复杂度4. 代码的重用5. 类函数的定义与使用5.1 定义类5.2 调用类函数1. 算法的定义及特点 …

_hand-2

实现一个迷你版的vue 入口 // js/vue.js class Vue {constructor (options) {// 1. 通过属性保存选项的数据this.$options options || {}this.$data options.data || {}this.$el typeof options.el string ? document.querySelector(options.el) : options.el// 2. 把da…

php mysql高校田径运动会成绩管理系统

第一章 引言 1 1.1 选题背景 1 1.2 编写目的 2 1.3 目标 2 1.4 功能需求 3 第二章 开发工具介绍 4 2.1 PHP 4 2.2 APACHE 5 2.3 MYSQL数据库 5 2.4 运行环境 WINDOWS XP 6 2.5 XAMPP 6 2.6 DREAMWEAVE8 6 2.7 EDITPLUS 7 第三章 需求…

【华为OD机试模拟题】用 C++ 实现 - 热点网络统计(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明热点网络统计【华为OD机试模拟题】题目输入输出描述示例一输入输出示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出…

C++入门知识【超详解】

目录1.认识Chello worldC关键字2.命名空间3.std标准库4.输入输出5.缺省参数6.函数重载7.引用7.1引用的概念7.2引用的场景1.作参数2.作返回值7.3引用的注意点7.4指针和引用的区别8.auto关键字9.基于范围的for循环10.内联函数10.1概念10.2特征11. C98中的指针空值1.认识C hello …

数据结构——单链表(上)

🌇个人主页:_麦麦_ 📚今日名言:“生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方。” ——海明威《永别了武器》 目录 ​编辑 一、前言 二、正言 3.1链表的概念及结构…

HMM(隐马尔科夫模型)-理论补充2

目录 一.大数定理 二.监督学习方法 1.初始概率 2.转移概率 3.观测概率 三.Baum-Welch算法 1.EM算法整体框架 2. Baum-Welch算法 3.EM过程 4.极大化 5.初始状态概率 6.转移概率和观测概率 四.预测算法 1.预测的近似算法 2.Viterbi算法 1.定义 2. 递推&#xff1…

倒计时2天:中国工程院院士谭建荣等嘉宾确认出席,“警务+”时代来临...

近日伴随公安部、科技部联合印发通知,部署推进科技兴警三年行动计划(2023-2025年),现代科技手段与警务工作相结合的方式,正式被定义为未来警务发展的新趋势。 21世纪以来,随着科技的不断发展和创新&#xf…

硬间隔支持向量机算法、软间隔支持向量机算法、非线性支持向量机算法详细介绍及其原理详解

相关文章 K近邻算法和KD树详细介绍及其原理详解朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解决策树算法和CART决策树算法详细介绍及其原理详解线性回归算法和逻辑斯谛回归算法详细介绍及其原理详解硬间隔支持向量机算法、软间隔支持向量机算法、非线性支持向量机算法详细…

JavaScript Date 日期对象实例合集

文章目录JavaScript Date 日期对象实例合集一,使用 Date() 方法获得当日的日期二,使用 getFullYear() 获取年份三,使用getTime() 返回从 1970 年 1 月 1 日至今的毫秒数四,如何使用 setFullYear() 设置具体的日期五,使…

小兔鲜注册页面验证、阶段案例(登录、首页页面)(重点)、小兔鲜放大镜效果——DOM

目录 1. 小兔鲜注册页面验证 2. 阶段案例(登录、首页页面)(重点) 3. 小兔鲜放大镜效果 1. 小兔鲜注册页面验证 验证码模块有个小问题: 连续点击获取验证码会导致触发多次计时器,会导致计时出现问题&…

【Stata】从入门到精通.零基础小白必学的教程,一学就fei

视频教程移步:https://www.bilibili.com/video/BV1hK4y1d714/?p4&spm_id_frompageDriver&vd_sourcecc8074e9c81a225f214226065db53d32P3 第二讲 Stata处理数据全流程(上) P3 - 01:37内置数据 file example datasets使用…

FastDFS - 分布式文件存储系统

目录一、分布式文件存储1.分布式文件存储的由来2.常见的分布式存储框架二、FastDFS介绍三、FastDFS安装1.拉取镜像文件2.构建Tracker服务3.构建Storage服务4.测试图片上传四、客户端操作1.Fastdfs-java-client1.1 文件上传1.2 文件下载2.SpringBoot整合一、分布式文件存储 1.分…

【MySQL】什么是意向锁 IS IX 及值得学习的思想

文章目录前言行锁和表锁使用意向锁意向锁的算法意向锁的思想JDK 中相似的思想前言 之前看 MySQL 都刻意忽略掉了 IS 和 IX 锁,今天看 《MySQL 是怎样运行的》,把意向锁讲的很通透,本篇博文提炼一下思想。 I: Intention Lock(意向…

自建服务器系列-0元搭建linux服务器(windows笔记本)

0元搭建linux服务器一.windows装Centos71.1 centos7 iso镜像1.2 准备U盘1.3 UltraISO 启动盘制作工具安装1.4 准备一台windows 机器1.5 安装过程二 、连接无线wifi三、固定wifi ip3.1 查看网络状态3.2 查看DNS3.3 查看GATEWAY3.4 设置静态IP四、一键快速安装单机版k8s五、申请域…

游戏高度可配置化:通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解

游戏高度可配置化:通数据引擎在模块化游戏开发中的应用构想图解 ygluu 码客 卢益贵 目录 一、前言 二、模块化与插件 1、常规模块化 2、插件式模块化(插件开发) 三、通用数据引擎理论与构成 1、名字系统(数据类型&#xf…

数据结构与算法之树结构基础

目录为什么要使用树结构树结构基本概念树的种类树的存储与表示常见的一些树的应用场景为什么要使用树结构 线性结构中不论是数组还是链表,他们都存在着诟病;比如查找某个数必须从头开始查,消耗较多的时间。使用树结构,在插入和查…

58-59-60 - 动态内存分配的实现

---- 整理自狄泰软件唐佐林老师课程 文章目录1. 讨论2. 动态内存管理2.1 动态内存管理的关键2.2 动态内存管理的分类3. 定长内存管理的设计与实现3.1 空间划分3.2 内存申请和归还3.3 关键数据类型3.4 思考4. 变长内存管理的设计与实现4.1 空间划分4.2 内存申请和归还4.3 关键数…

802.11 MCS 的最低SNR分析

常常看到这样的表格: 那么这个SNR如何而来? 看看RSSI和SNR的关系,它们之间隔了一个noise floor。从表格看得出,这个底噪在-80~-90之间。 而SNR的核心,也有类似的原因,它和BER有关。

tkinter界面的TCP通信/开启线程等待接收数据

前言 用简洁的语言写一个可以与TCP客户端实时通信的界面。之前做了一个项目是要与PLC进行信息交互的界面,在测试的时候就利用TCP客户端来实验,文末会附上TCP客户端。本文分为三部分,第一部分是在界面向TCP发送数据,第二部分是接收…