当前位置: 首页 > news >正文

atomic 原子操作

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 and34  * store exclusive to ensure that these are atomic.  We may loop35  * 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的支持。

相关文章:

atomic 原子操作

atomic 原子操作前言atomic_t定义内核中的实现armv7的实现armv8的实现Exclusive monitor实现所处的位置External exclusive monitorAtomic指令的支持QA前言 修改一个变量会经过读、修改、写的操作序列。但有时该操作序列在执行完毕前会被其他任务或事件打断。 比如在多CPU体系…...

DataGear 制作基于Vue前端框架渲染的数据可视化看板

DataGear 在4.3.0版本新增了dg-dashboard-code特性&#xff0c;并在4.4.0版本进行了改进和增强&#xff0c;结合看板API&#xff0c;可以很方便地制作完全由Vue、React等前端框架渲染的数据可视化看板。 本文基于Vue2、Element UI前端框架的<el-container>、<el-head…...

JavaFX Scene Builder 下载安装

JavaFX Scene Builder 下载安装1. Scene Builder官网下载2. 安装3. Oracle官网下载Scene Builder 是创建漂亮的用户界面&#xff0c;并将您的设计转化为交互式原型。Scene Builder通过创建可以直接在JavaFX应用程序中使用的用户界面&#xff0c;缩小了设计人员和开发人员之间的…...

dva( 轻量级的应用框架 )

dva核心知识与实战运用 dva 首先是一个基于 redux 和 redux-saga 的数据流方案&#xff0c;然后为了简化开发体验&#xff0c;dva 还额外内置了 react-router 和 fetch&#xff0c;所以也可以理解为一个轻量级的应用框架! 介绍 | DvaJS 易学易用&#xff0c;仅有 6 个 api&…...

数据结构:堆的实现与建堆时间复杂度分析

目录 前言 一.堆的介绍 1.堆的本质 2.堆的分类 二.堆的实现(以小根堆为例) 1.关于二叉树的两组重要结论&#xff1a; 2.堆的物理存储结构框架(动态数组的简单构建) 3. 堆元素插入接口(以小根堆为例) 堆尾元素向上调整的算法接口: 4.堆元素插入接口测试 5.堆元素插入…...

对“车辆销售配置器”的认识与理解

概述 中国汽车市场转为存量阶段后&#xff0c;各车企开始从”以产品为中心“转型到”以客户为中心“&#xff0c;产品的个性化配置需求日益丰富。随着竞争的加剧&#xff0c;车企们不仅要提供出色的产品&#xff0c;而且需要提供更加个性化的产品配置和服务&#xff0c;例如&am…...

Linux编译器——gcc/g++(预处理、编译、汇编、链接)

目录 0.程序实现的两大环境 1.gcc如何完成 预处理 编译 汇编 链接 2.动态库与静态库 对比二者生成的文件大小 3. gcc常用选项 0.程序实现的两大环境 任何一个C程序的实现都要经过翻译环境与执行环境。 在翻译环境中又分为4个部分&#xff0c;预编译、编译、汇编与链…...

Java 操作图片进行缩放旋转翻转加水印

1 纯原生手写图片操作工具类 import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; public class RotateImageUtil {public static BufferedImage rotateImage(BufferedImage bu…...

不能去演唱会现场就多听听耳机里的他们,教你用python来实现一个音乐播放器

前言 最近可以说大麦网很知名了&#xff0c;哈哈还有好多想要用Python来搞抢票脚本的 怎么说呢也不是不行&#xff0c;但是咱今天可不是来搞这个的&#xff0c;我可不抢票&#xff0c;抢了都去不了&#xff0c;上班搞钱啊铁铁们 咱就是说去不了现场&#xff0c;就多听听手机…...

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

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

·神经网络

目录11神经网络demo112神经网络demo213神经网络demo320tensorflow2.0 安装教程,所有安装工具&#xff08;神经网络&#xff09;21神经网络-线性回归- demo122神经网络-线性回归- demo228神经网络-多层感知- demo1目录11神经网络demo1 package com.example.xxx; import java.ut…...

【Java 多线程学习】

多线程学习多线程1. 并行与并发2.进程和线程3. *****多线程的实现方式3.1 继承Thread类的方式进行实现3.2 实现Runnable接口方式进行实现3.3 利用Callable和Future接口方式实现3.4 设置获取线程名字4.获得线程对象5.线程休眠6.线程调度[线程的优先级]7.后台线程/守护线程多线程…...

【计算机考研408】快速排序的趟数问题 + PAT 甲级 7-2 The Second Run of Quicksort

前言 该题还未加入PAT甲级题库中&#xff0c;可以通过购买2022年秋季甲级考试进行答题&#xff0c;纯考研题改编 快速排序 常考的知识点 快速排序是基于分治法快速排序是所有内部排序算法中平均性能最优的排序算法快速排序是一种不稳定的排序算法快速排序算法中&#xff0c…...

CSS-Grid(网格)布局

前言 之前HTML 页面的布局基本上都是通过 Flexbox 来实现的&#xff0c;能轻松的解决复杂的 Web 布局。 现在又出现了一个构建 HTML 最佳布局体系的新竞争者。就是强大的CSS Grid 布局。 grid和flex区别是什么&#xff1f;适用什么场景&#xff1f; Flexbox 是一维布局系统&am…...

软件测试4

一 form表单标签 1.form表单标签里面就是所有用户填写的表单数据&#xff1b; action“xxx.py”把表单数据提交给哪一个后台程序去处理 method“post” 传递数据时候的方式方法&#xff0c;post代表隐式提交数据、get明文传送数据 2.input标签的type类型 type“text” 普通的输…...

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

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

每日学术速递3.1

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Directed Diffusion: Direct Control of Object Placement through Attention Guidance 标题&#xff1a;定向扩散&#xff1a;通过注意力引导直接控制物体放置 作者&#xff1a;…...

金融行业数据模型

一、Teradata FS-LDM Teradata 公司基于金融业务发布的FS-LDM&#xff08;Financial Servies Logical Data Model&#xff09; 十大主题&#xff1a;当事人、产品、协议、事件、资产、财务、机构、地域、营销、渠道。 1、当事人&#xff08;Party&#xff09; 银行所服务的任…...

【面试题】2023前端vue面试题及答案

Vue3.0 为什么要用 proxy&#xff1f;在 Vue2 中&#xff0c; 0bject.defineProperty 会改变原始数据&#xff0c;而 Proxy 是创建对象的虚拟表示&#xff0c;并提供 set 、get 和 deleteProperty 等处理器&#xff0c;这些处理器可在访问或修改原始对象上的属性时进行拦截&…...

(哈希查找)leetcode128. 最长连续序列

文章目录一、题目1、题目描述2、基础框架3、原题链接二、解题报告1、思路分析2、时间复杂度3、代码详解三、本题小知识一、题目 1、题目描述 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。…...

PyTorch 2.8镜像部署教程:适配550.90.07驱动的GPU监控与显存优化技巧

PyTorch 2.8镜像部署教程&#xff1a;适配550.90.07驱动的GPU监控与显存优化技巧 1. 镜像概述与环境准备 PyTorch 2.8深度学习镜像专为RTX 4090D 24GB显卡和CUDA 12.4环境深度优化&#xff0c;预装了完整的深度学习工具链。这个镜像已经过严格测试&#xff0c;确保在550.90.0…...

雨课堂运动与健康网课高效学习指南

1. 雨课堂运动与健康网课学习资源整合 第一次接触雨课堂的运动与健康网课时&#xff0c;我和很多同学一样手忙脚乱。平台上的资料分散在各个角落&#xff0c;视频、文档、测试题混在一起&#xff0c;根本不知道从哪里开始。后来摸索出一套资源整理方法&#xff0c;效率直接翻倍…...

PCB设计实战:数字模拟隔离的元件抉择——从0Ω电阻到磁珠的精准应用

1. 数字模拟隔离的基础原理与挑战 在混合信号电路设计中&#xff0c;数字电路和模拟电路就像两个性格迥异的邻居。数字电路工作时会产生高频开关噪声&#xff0c;就像隔壁装修时的电钻声&#xff1b;而模拟电路对噪声极其敏感&#xff0c;如同正在录音的麦克风。这时候&#xf…...

6个高效突破内容访问限制的开源工具使用指南

6个高效突破内容访问限制的开源工具使用指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的数字时代&#xff0c;优质内容常常被付费墙限制访问。本文将系统介绍基于开源…...

UEFI安全启动恢复流程文档:详细操作指南与故障排除

UEFI安全启动恢复流程文档&#xff1a;详细操作指南与故障排除 【免费下载链接】edk2 EDK II 项目地址: https://gitcode.com/gh_mirrors/ed/edk2 UEFI安全启动是现代计算机系统的重要安全功能&#xff0c;它通过数字签名验证确保只有受信任的操作系统和引导加载程序能够…...

Insanely Fast Whisper终身学习模型:持续优化的语音识别系统设计

Insanely Fast Whisper终身学习模型&#xff1a;持续优化的语音识别系统设计 【免费下载链接】insanely-fast-whisper 项目地址: https://gitcode.com/GitHub_Trending/in/insanely-fast-whisper 你是否还在为语音识别速度慢、准确率低而烦恼&#xff1f;是否希望拥有一…...

Offline-First数据同步策略:解决网络中断的智能方案

Offline-First数据同步策略&#xff1a;解决网络中断的智能方案 【免费下载链接】offline-first :electric_plug: Everything you need to know to create offline-first web apps. 项目地址: https://gitcode.com/gh_mirrors/of/offline-first 在当今移动优先的时代&am…...

vLLM-v0.17.1实战案例:为AI编程助手提供毫秒级代码补全服务

vLLM-v0.17.1实战案例&#xff1a;为AI编程助手提供毫秒级代码补全服务 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库&#xff0c;其核心目标是提供极致的推理速度和易用性。这个项目最初由加州大学伯克利分校的天空计算实验室开发&#xff0c;…...

无代码爬虫方案:OpenClaw调度Qwen3.5-9B解析动态网页数据

无代码爬虫方案&#xff1a;OpenClaw调度Qwen3.5-9B解析动态网页数据 1. 为什么需要无代码爬虫&#xff1f; 作为一个经常需要从网页抓取数据的技术博主&#xff0c;我经历过太多抓取数据的痛苦时刻。传统爬虫开发需要处理反爬机制、解析动态加载内容、维护复杂的XPath或CSS选…...

Windows下OpenClaw全流程指南:GLM-4.7-Flash模型接入与自动化测试

Windows下OpenClaw全流程指南&#xff1a;GLM-4.7-Flash模型接入与自动化测试 1. 为什么选择OpenClawGLM-4.7-Flash组合 去年我在处理一个Python数据分析项目时&#xff0c;每天要重复执行十几个脚本并整理结果。当我第三次因为手工操作失误导致数据错乱后&#xff0c;终于决…...