• 浅析ARMv8体系结构:原子操作


    概述

    在编程中,当多个处理器或线程访问共享数据,并且至少有一个正在写入时,操作必须是原子的,这意味着数据访问必须被视为相对于其他处理器的单个操作,以避免数据竞争条件。

    原子操作的实现依赖处理器硬件提供支持,在不同的处理器体系结构上,原子操作会有不同的实现,例如在x86体系结构下,通常使用锁缓存/总线的方式实现原子操作。目前在ARMv8体系结构下支持两种方式来实现原子操作:

    • 一种是经典的独占内存访问机制,也叫做LL/SC(Load-Link/Store-Conditional),早期ARM体系结构下的原子操作都是基于这种方式实现;
    • 另一种是ARMv8.1体系结构上新增的LSE(Large System Extension)扩展,LSE提供了多种原子内存访问操作指令。

    LL/SC机制

    LL/SC机制使用多个指令,并且每个处理器都需要实现一个专有监视器,LL/SC机制利用独占内存访问指令和独占监视器共同实现原子操作。首先看下ARMv8体系结构提供的独占内存访问指令。

    独占内存访问指令

    ARMv8体系结构实现的独占内存访问指令为LDXR/STXR:

    • LDXR:内存独占加载指令,它从内存中以独占方式加载内存地址的值到寄存器中;
    • STXR:内存独占存储指令,它以独占的方式把数据存储到内存中。

    LDXR/STXR的指令格式如下:

    ldxr    , [xn | sp] 
    stxr    , , [xn | sp]
    
    • 1
    • 2
    多字节独占内存访问指令

    LDXP和STXP指令是多字节独占内存访问指令,一条指令可以独占地加载和存储16字节。

    ldxp    , , [xn | sp]
    stxp    , , , []
    
    • 1
    • 2

    独占监视器

    独占监视器是一个硬件状态机,用于跟踪读-修改-写序列,并支持Load和Store操作。当CPU执行LDXR指令时,独占监视器会把对应内存地址标记为独占访问模式,保证以独占的方式来访问这个内存地址;而STXR是有条件的存储指令,当CPU执行STRX指令将新数据写入到LDXR指令标记的独占访问内存地址时,会根据独占监视器的状态来进行处理:

    • 若独占监视器为独占访问状态,那么STRX指令执行成功,并且独占监视器会切换状态到开放访问状态;
    • 若独占监视器为开放访问状态,则STRX指令执行失败,数据无法存储。

    ARMv8体系提供了三类独占监视器:

    • 本地独占监视器
    • 内部缓存一致性全局独占监视器
    • 外部全局独占监视器

    这些独占监视器分别位于系统存储结构的不同层次,如下
    在这里插入图片描述

    经典自旋锁实现

    如下是一个经典的基于独占访问机制的自旋锁实现:
    在这里插入图片描述

    LSE机制

    LL/SC操作本质上是多个CPU核竞争某个内存变量的独占访问,当系统处理器的数量很少时,这可以正常工作;当增加处理器的数量时,处理器之间的竞争冲突会加剧,这会严重影响系统系统;再加上Cache的影响,先前访问到内存变量的处理器会更容易再次获得变量的访问权,这使得多核间访问变量的公平性也难以保证。

    Armv8.1-A架构引入了新的原子操作指令,即LSE,LSE机制用于替代原来的LL/SC机制。LSE提升了多处理器系统中原子操作的性能,使用LSE,可以在单个指令中提供不可中断的读-修改-写序列。原子指令可以在指定的内存位置上执行简单的算术或逻辑操作,并将更新的值返回给处理器。LSE新增了三类指令:

    • 原子内存操作指令,包含LD和ST,其中可以是ADD、CLR、EOR、SET、SMAX、SMIN、UMAX和UMIN;
    • 比较并交换指令,包括CAS和CASP
    • 交换指令,SWP

    原子内存操作指令

    原子内存操作指令分成两类:原子加载指令和原子存储指令。原子内存访问指令的格式如下:

    ld  , , []
    st  , []
    
    • 1
    • 2

    支持的原子操作后缀:
    在这里插入图片描述

    CAS指令

    CAS指令的格式如下

    cas , , [{,#0}]
    cas , , [{,#0}]
     
    casp , , , , [{,#0}]
    casp , , , , [{,#0}]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    交换指令

    交换指令的指令格式如下:

    swp , , []
    swp , , []
    
    • 1
    • 2

    相关参考

  • 相关阅读:
    考研程序设计100题系列(21-30题)
    【JavaScript高级】ES6常见新特性:词法环境、let、const、模板字符串、函数增强、Symbol、Set、Map
    React中路由操作、页面跳转
    pandas读取一个 文件夹下所有excel文件
    typedef和#define的花里胡哨的用法
    Interactive Tools Recommendation System integrating QT/ROS /Pytorch
    想进入游戏建模行业,这4点必须了解
    热启动和冷启动是什么,区别
    为什么要urlencode?
    1 论文笔记:Efficient Trajectory Similarity Computation with ContrastiveLearning
  • 原文地址:https://blog.csdn.net/anyegongjuezjd/article/details/136311655