atomic 原子操作

news2024/11/16 3:47:29

atomic 原子操作

  • 前言
  • atomic_t定义
  • 内核中的实现
    • armv7的实现
    • armv8的实现
  • Exclusive monitor实现所处的位置
  • External exclusive monitor
  • Atomic指令的支持
  • QA

前言

修改一个变量会经过读、修改、写的操作序列。但有时该操作序列在执行完毕前会被其他任务或事件打断。
比如在多CPU体系结构中,运行在两个CPU上的两个内核控制路径同时并行执行上面操作序列,有可能发生下面的场景:
在这里插入图片描述
在单CPU上也会由于有多个内核控制路径的交错而导致这种情况:
在这里插入图片描述

atomic_t定义

linux专门定义了一种只进行原子操作的类型atomic_t

166 typedef struct {
167     int counter;
168 } atomic_t;

具体的接口API函数整理如下:
在这里插入图片描述

内核中的实现

armv7的实现

 36 #define ATOMIC_OP(op, c_op, asm_op)                 \
 37 static inline void arch_atomic_##op(int i, atomic_t *v)         \
 38 {                                   \
 39     unsigned long tmp;                      \
 40     int result;                         \
 41                                     \
 42     prefetchw(&v->counter);                     \
 43     __asm__ __volatile__("@ atomic_" #op "\n"           \
 44 "1: ldrex   %0, [%3]\n"                     \
 45 "   " #asm_op " %0, %0, %4\n"                   \
 46 "   strex   %1, %0, [%3]\n"                     \
 47 "   teq %1, #0\n"                       \
 48 "   bne 1b"                         \
 49     : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)       \
 50     : "r" (&v->counter), "Ir" (i)                   \
 51     : "cc");                            \
 52 } 

ARMv6之前的CPU并不支持SMP,原子操作就是通过关闭CPU中断来完成的。ARMv6之后的ARM架构都是支持SMP的。ARM V7之后的LDREX、STREX指令可以解决这个问题。它保证2个读-修改-写序列有交叉的时候,只有1个可以写成功,另外一个则再次尝试。

汇编嵌入c代码的语法:嵌入式汇编的语法格式是:asm(code : output operand list : input operand list : clobber list)。output operand list 和 input operand list是c代码和嵌入式汇编代码的接口,clobber list描述了汇编代码对寄存器的修改情况。大家对着上面的code就可以分开各段内容了。@符号标识该行是注释。这里的__volatile__主要是用来防止编译器优化的。

我们先看ldrex和strex这两条汇编指令的使用方法。ldr和str这两条指令大家都是非常的熟悉了,后缀的ex表示Exclusive,是ARMv7提供的为了实现同步的汇编指令。
STREX指令,除了把寄存器的值写入一个地址以外,还可以返回这次写是否成功.

STREXEQ r0, r1, [LockAddr]
上述指令把r1写入地址LockAddr,如果写入成功,则r0=0,否则r0不等于0。如果r0不等于0,证明写入失败,那么需要重新来ldrex,重新来修改和写。官方解释如下:

The STREX instruction performs a conditionalstore of a word to memory. If the exclusive monitor(s) permit thestore, the operation updates the memory location and returns the value0 in the destination register, indicating that the operation succeeded.If the exclusive monitor(s) do not permit the store, the operationdoes not update the memory location and returns the value 1 in thedestination register. This makes it possible to implement conditionalexecution paths based on the success or failure of the memory operation.For example, STREX R2, R1, [R0] performs a Store-Exclusiveoperation to the address in R0, conditionallystoring the value from R1 and indicating successor failure in R2.

当两个LDREX,STREX序列交错的时候,谁先STREX,谁成功,第2个STREX失败,重新来LDREX。

armv8的实现

在ARMv8 架构下对应的是LDXR (load exclusive register 和STXR (store exclusiveregister)及其变种指令。

 32 /*
 33  * AArch64 UP and SMP safe atomic ops.  We use load exclusive and
 34  * store exclusive to ensure that these are atomic.  We may loop
 35  * to ensure that the update happens.
 36  */
 37 
 38 #define ATOMIC_OP(op, asm_op, constraint)               \
 39 static inline void                          \
 40 __ll_sc_atomic_##op(int i, atomic_t *v)                 \
 41 {                                   \
 42     unsigned long tmp;                      \
 43     int result;                         \
 44                                     \
 45     asm volatile("// atomic_" #op "\n"              \
 46     __LL_SC_FALLBACK(                       \
 47 "   prfm    pstl1strm, %2\n"                    \
 48 "1: ldxr    %w0, %2\n"                      \
 49 "   " #asm_op " %w0, %w0, %w3\n"                \
 50 "   stxr    %w1, %w0, %2\n"                     \
 51 "   cbnz    %w1, 1b\n")                     \
 52     : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)        \
 53     : __stringify(constraint) "r" (i));             \
 54 }

LDXR/ STXR和一般的LDR/STR的区别就在于LDXR除了向memory发起load请求外,还会记录该memory所在地址的状态(一般ARM处理器在同一个cache line大小,也就是64 byte的地址范围内共用一个状态),那就是Open和Exclusive。
我们可以认为一个叫做exclusive monitor的模块来记录。根据CPU访问内存地址的属性(在页表里面定义),这个组件可能在处理器 L1 memory system, 处理器cluster level, 或者总线,DDR controller上。

下面是Arm ARM架构 [1] 文档定义的状态转换图

在这里插入图片描述
实例说明:
1)thread1发起了一个LDXR的读操作,记录当前的状态为Exclusive

2)thread2发起了一个LDXR的读操作,当前的状态为Exclusive,保持不变

3)thread2发起了一个STXR的写操作,状态从Exclusive变成Open,同时数据回写到DDR

4)thread1发起了一个STXR的写操作,因为当前的exclusive monitor状态为Open,写失败(假如程序这时用STR操作来写,写会成功,但是这个不是原子操作函数的本意,属于编程错误)
在这里插入图片描述
假如有多个CPU,同时对一个处于Exclusive的memory region来进行写,CPU有内部逻辑来保证串行化。

Monitor的状态除了STXR会清掉,从Exclusive变成Open之外,还有其他因素也可以导致monitor的状态被清掉,所以软件在实现spinlock的时候,一般会用一个loop循环来实现,所谓“spin”。

Exclusive monitor实现所处的位置

根据LDXR/STXR 访问的memory的属性,需要的monitor可以在CPU内部,总线,也可以DDR controller(例如ARM DMC-400 [2]在每个memory interface 支持8个 exclusive access monitors)。

一般Memory属性配置为 normal cacheable, shareable,这种情形下,CPU发起的exclusive access会终结在CPU cluster内部,对外的表现,比如cacheline fill和line eviction和正常的读写操作产生的外部行为是一样的。具体实现上,需要结合local monitor的状态管理和cache coherency 的处理逻辑,比如MESI/MOESI的cacheline的状态管理来。

为方便大家理解,下面划出一个monitor在一个假象SOC里面的逻辑图(在一个真实芯片里面,不是所有monitor都会实现,需要和SOC vendor确认)
在这里插入图片描述

External exclusive monitor

对于normal non-cacheable,或者Device类型的memory属性的memory地址,cpu会发出exclusive access的AXI 访问(AxLOCK signals )到总线上去,总线需要有对应的External exclusive monitor支持,否则会返回错误。例如, 假如某个SOC不支持外部global exclusivemonitor,软件把MMU disabled的情况下,启动SMP Linux,系统是没法启动起来的,在spinlock处会挂掉。
AMBA AXI/ACE 规范:

The exclusive access mechanism can provide semaphore-type operations without requiring the bus to remain dedicated to a particular master for the duration of the operation. This means the semaphore-type operations do not impact either the bus access latency or the maximum achievable bandwidth.

The AxLOCK signals select exclusive access, and the RRESP and BRESP signals indicate the success or failure of the exclusive access read or write respectively.

The slave requires additional logic to support exclusive access. The AXI protocol provides a mechanism to indicate when a master attempts an exclusive access to a slave that does not support it. 

Atomic指令的支持

处理器,支持cache coherency协议的总线,或者DDR controller可以增加了一些简单的运算,比如,在读写指令产生的memory访问的过程中一并把简单的运算给做了。

AMBA 5 [3] 里面增加了对Atomic transactions的支持:

AMBA 5 introduces Atomic transactions, which perform more than just a single access, and have some form of operation that is associated with the transaction.

Atomic transactions are suited to situations where the data is located a significant distance from the agent that must perform the operation. Previously, performing an operation that is atomically required pulling the data towards the agent, performing the operation, and then pushing the result back.

Atomic transactions enable sending the operation to the data, permitting the operation to be performed closer to where the data is located.

The key advantage of this approach is that it reduces the amount of time during which the data must be made inaccessible to other agents in the system

支持4种Atomic transaction:AtomicStore ,AtomicLoad,AtomicSwap 和AtomicCompare

QA

(1) Local monitor和Global monitor的使用场景

  • Local monitor适用于访问的memory属为normal cacheable, shareable或者non-shareable的情况.

  • Global monitor ,准确来说,external global exclusive monitor (处理器之外,在外部总线上)用于normal noncacheable或者device memory类型。比如可以用于一个Cortex-A处理器和一个Cortex-M 处理器(没有内部cache)之间的同步。

(2) 多CPU下,多个LDREX,和STREX的排他性实现

  • 各个处理器和总线的实现不同,可以从软件上理解为和data coherency实现相结合,比如M(O)ESI协议[5],这是一种 Invalidate-based cache coherence protocol, 其中的key point就是当多个CPU在读同一个cacheline的时候,在每个CPU的内部cache里面都有cacheline allocation, cacheline的状态会变成Shared;但是当某个CPU做写的时候,会把其它CPU里面的cacheline数据给invalidate掉,然后写自己的cacheline数据,同时设置为Modified状态,从而保证了数据的一致性。

  • LDREX,本质上是一个LDR,CPU1做cache linefill,然后设置该line为E状态(Exclusive),额外的一个作用是设置exclusive monitor的状态为Exclusive;其他cpu做LDREX,该line也会分配到它的内部cache里面,状态都设置为Shared ,也会设置本CPU的monitor的状态。当一个CPU 做STREX时候,这个Write操作会把其它CPU里面的cacheline数据给invalidate掉。同时也把monitor的状态清掉,从Exclusive变成Open的状态,这个MESI协议导致cachline的状态在多CPU的变化,是执行Write操作一次性改变的。这样在保证数据一致性的同时,也保证了montitor的状态更新同步改变。

(3) 比如举一个多核的场景,一个核ldrex了,如果本核的local monitor会发生什么,外部的global monitor发生什么,开不开mmu,cache不cache,区别和影响是什么。

Ldrex/strex本来就是针对多核的场景来设计的,local monitor的状态发生改变,不会影响外部的global monitor状态。但是external global monitor的状态发生改变,可以告诉处理器,把local monitor的状态清掉。

Data coherency是通过硬件来支持的。对于normal cacheable类型的memory, MMU和DCache必须使能,否则CPU会把exclusive类型的数据请求发出处理器,这时需要外部monitor的支持。

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

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

相关文章

python基础学习3--切片(slice)

在python中,切片(slice)是对序列型对象(如list,string,tuple)的一种高级索引方法。普通索引只取出序列一个下标对应的元素,而切片取出序列中一个范围对应的元素,这里的范围不是狭义上的连续片段。通俗一点就…

CLion Debug 调试 Makefile 构建的 C 语言程序断点不起作用

最近在研究 jattach,打算在本地调试项目,发现 CLion 可以正常编译运行代码,却无法断点 Debug。由于笔者对 C/C 项目不熟悉,在此记录研究过程中遇到的一些基本问题与解决方法。 文章目录解决方式尝试过的手段【未解决】找 Native D…

RIG Exploit Kit 仍然通过 IE 感染企业用户

RIG Exploit Kit 正处于最成功的时期,每天尝试大约 2000 次入侵并在大约 30% 的案例中成功,这是该服务长期运行历史中的最高比率。 通过利用相对较旧的 Internet Explorer 漏洞,RIG EK 已被发现分发各种恶意软件系列,包括 Dridex…

内科大机器学习期末重点

1. 什么是机器学习 (由于图床原因导致部分图片错位,可以借鉴着看) 语音识别算法推荐人脸识别垃圾邮件过滤贷款资格审核 2. 学习的概念 与经验有关 学习可以改善系统性能 学习是一个有反馈的信息处理与控制过程 3. 学习分类&#xff1a…

996的压力下,程序员还有时间做副业吗?

996怎么搞副业? 这个问题其实蛮奇怪的:996的压力下,怎么会还想着搞副业呢? 996还想搞副业的原因有哪些? 大家对于996应该都不陌生,总结就是一个字:忙。 996的工作性质就是加班,就…

基于龙芯+国产FPGA 的VPX以太网交换板设计(二)

3.1 板卡技术要求 3.1.1 主要性能指标 本着向下兼容的原则,以太网交换板的设计尽量保留传统信息处理平台的基本功 能和接口,重点考虑提升设备的性能和扩展性。本课题以太网交换板的主要性能指标 如下: (1) 具有大容量无…

一文搞懂华为防火墙的原理和配置

“防火墙”一词起源于建筑领域,用来隔离火灾,阻止火势从一个区域蔓延到另一个区域。引入到通信领域,防火墙这一具体设备通常用于两个网络之间有针对性的、逻辑意义上的隔离。这种隔离是选择性的,隔离“火”的蔓延,而又…

mac安装docker hub及使用

1. docker hub安装 官网:Docker https://hub.docker.com/ 去官网 下载 Docker.dmg 并安装 2. docker hub的使用 step1: 首先克隆一个仓库 Getting Started 项目是一个简单的Github仓库,他包含了你创建镜像的所有东西,并且可以把他当容…

文心一言的蝴蝶振翅,云计算的飓风狂飙

ChatGPT带来的多米诺效应正在不断涌现。社会各界都在关注一系列问题,比如中国版ChatGPT什么时候能来到?其效果如何?类ChatGPT应用的投资与创业前景会怎样?相关产品能带来哪些应用价值?随着百度文心一言等产品相继官宣&…

面试问题【数据库】

数据库数据库的三范式是什么drop、delete、truncate 分别在什么场景之下使用char 和 varchar 的区别是什么数据库的乐观锁和悲观锁是什么SQL 约束有哪几种mysql 的内连接、左连接、右连接有什么区别MyIASM和Innodb两种引擎所使用的索引的数据结构是什么mysql 有关权限的表都有哪…

SpringSecurity常见面试题汇总(超详细回答)

1.什么是Spring Security?核心功能?Spring Security是一个基于Spring框架的安全框架,提供了完整的安全解决方案,包括认证、授权、攻击防护等功能。其核心功能包括:认证:提供了多种认证方式,如表…

线性表 链表表示

初识链表 用一组物理位置任意的存储单元来存放线性表的数据元素。这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。链表中元素的逻辑次序和物理次序不一定相同。 在存储自己内容的同时也存储下一个元素的地址。存…

Adobe illustrator使用教程

抓手工具:绘制大型图片拖动图片 画放大缩小:Alt鼠标滚轮 间接选择工具:点击图标shift 进行多个对象选择,再次点击取消选择(用于对多个对象进行批量操作) 直接选择工具:可以对图案本身进行精细选…

(二十二)操作系统-生产者·消费者问题

文章目录一、问题描述二、问题分析三、PV操作题目分析步骤1. 关系分析2. 整理思路3. 设置信号量4. 编写代码四、能否改变相邻P、V操作的顺序?五、小结1. PV操作题目的解题思路2. 注一、问题描述 系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品…

什么是文件传输中台?

企业文件传输的场景有哪些? 企业日常办公中无时无刻不在产生数据文件。多样化的数据已成为企业的重要资产,更被称为是“新石油”。数据并不是单单存储起来就行了,而是需要高效又安全的让数据流转起来,释放其自身的价值&#xff0…

XGBoost和LightGBM时间序列预测对比

XGBoost和LightGBM都是目前非常流行的基于决策树的机器学习模型,它们都有着高效的性能表现,但是在某些情况下,它们也有着不同的特点。 XGBoost和LightGBM简单对比 训练速度 LightGBM相较于xgboost在训练速度方面有明显的优势。这是因为Ligh…

发票自动OCR识别并录入模板 3分钟免费配置

要问整个公司里和数据打交道最多的职能,非财务莫属了吧。除了每天要处理大量财务数据外,还有发票录入的工作让财务陷入“易燃易爆炸”的工作状态。发票报销看似简单,但发票的类型有很多种,每种发票需要录入的信息也有差别。再加上…

SimpleITK 获取CT spacing 底层原理

SimpleITK 获取CT spacing 底层原理 一、层厚、层间距概念 层厚: CT扫描机扫描出来的断层的层的厚度, 通常用Slice thickness表示, 比如 5mm 层间隔:一般用 Slice interval 或 Slice increment来表示,比如 5mm。在 …

最新!蔚来2022年第四季度被理想汽车超越,或将在2023年全面落后

3月1日,蔚来汽车(NYSE: NIO; HKEX: 9866; SGX: NIO,下称“蔚来”)发布了截至2022年12月31日的第四季度及全年财报。财报显示,蔚来2022年第四季度实现营收160.64亿元(约23.29亿美元),…

SpringBoot实现静态资源映射,登录功能以及访问拦截验证——以黑马瑞吉外卖为例

目录 一、项目简介 二、设置静态资源访问路径 三、实现登录功能 四、拦截访问请求 本篇文章以黑马瑞吉外卖为例 一、项目简介 瑞吉外卖项目分为后台和前台系统,后台提供给管理人员使用,前台则是用户订餐使用 资源我们放在resources下 二、设置静态…