CAS操作的底层原理(总线锁定机制和缓存锁定机制 )

devtools/2025/1/14 10:40:20/

目录

处理器级别的实现

总线锁定机制

缓存锁定机制 

MSEI表示缓存行的四种状态

MESI协议状态转换

CAS%E6%93%8D%E4%BD%9C%E6%98%AF%E4%B8%8D%E4%BF%9D%E8%AF%81%E5%8F%AF%E8%A7%81%E6%80%A7%E7%9A%84-toc" style="margin-left:80px;">CAS操作是不保证可见性的

CAS%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5-toc" style="margin-left:80px;">CAS基本概念

ABA问题的处理

性能考虑 


先总结一下,CAS(Compare And Swap)是一种原子操作,它比较当前内存值与期望值,如果相等则更新为新值,CAS是一种硬件级的原子操作,通过总线锁或缓存锁实现原子性,在使用缓存锁的时候缓存一致性协议保证数据一致性。

而Java通过native方法调用底层CAS指令,需要考虑ABA问题和性能优化,而cas这种机制保证了在多处理器系统中的原子操作,是实现无锁并发的基础。

处理器级别的实现

x86汇编中的CMPXCHG指令示例
lock cmpxchg [内存地址], 新值

处理器通过特殊的指令(如x86的CMPXCHG)来实现CAS操作,并使用LOCK前缀保证操作的原子性。 

总线锁定机制

CPU1 ----┐
CPU2 ----├── 总线 -----> 内存
CPU3 ----┘
         ↑
      LOCK信号 

当一个CPU发出LOCK信号时,其他CPU无法通过总线访问内存,保证了操作的原子性。但这种方式开销较大。

缓存锁定机制 

CPU1 Cache [数据A: M] ─┐
CPU2 Cache [数据A: I]   ─┼── 总线 ──> 内存[数据A]
CPU3 Cache [数据A: I]   ─┘

使用缓存一致性协议(MESI),通过缓存状态控制来保证原子性,效率更高。

MSEI表示缓存行的四种状态

M(Modify)表示共享数据只缓存在当前 CPU 缓存中, 并且是被修改状态,也就是缓存的数据和主内存中的数据不一致

E(Exclusive)表示缓存的独占状态,数据只缓存在当前 CPU 缓存中,并且没有被修改

S(Shared)表示数据可能被多个 CPU 缓存,并且各个缓存中的数据和主内存数据一致

I(Invalid)表示缓存已经失效

MESI协议状态转换

CPU1执行CAS
1. 发出监听请求
2. 等待其他CPU响应
3. 确认无冲突后执行
4. 广播状态变更

CPU在读取一个数据时会先发起监听,去监听其他CPU的对这个数据缓存行的状态。

如果本CPU缓存行状态是I,则需要从内存中读取,并把缓存行状态置为S。

如果本CPU缓存行的状态不是I,则可以直接读取缓存中的值,如果其他CPU也有该数据的缓存且状态是M,则需要等待其把缓存更新到内存后再读取。

CPU更新了缓存行的状态了之后会发广播来更新其他CPU的缓存行状态。

CAS%E6%93%8D%E4%BD%9C%E6%98%AF%E4%B8%8D%E4%BF%9D%E8%AF%81%E5%8F%AF%E8%A7%81%E6%80%A7%E7%9A%84">CAS操作是不保证可见性的

这一点要特别注意,CAS的操作是不保证可见性的,可见性是实现CAS操作的前提,如果连可见性都保证不了,这又怎么实现CAS操作?

CAS操作通常与volatile配合使用,通过内存屏障保证可见性。

CAS%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5">CAS基本概念

java">// CAS操作的伪代码
public boolean compareAndSet(int expectedValue, int newValue) {// 原子操作,比较并交换// V是要更新的变量,E是期望值,N是新值if (V == expectedValue) {V = newValue;return true;}return false;
}

 CAS(Compare And Swap)是一种原子操作,它比较当前内存值与期望值,如果相等则更新为新值。

ABA问题的处理

 

java">public class AtomicStampedReference<V> {private static class Pair<T> {final T reference;final int stamp;private Pair(T reference, int stamp) {this.reference = reference;this.stamp = stamp;}}
}

ABA是CAS操作的经典问题了,可以通过版本号或时间戳解决ABA问题。

性能考虑 

java">// 自旋等待示例
public void spinLock() {while (!cas.compareAndSet(false, true)) {// 自旋等待Thread.onSpinWait(); // Java 9+}
}

CAS失败时通常采用自旋等待,需要考虑自旋次数和退避策略。 

 


http://www.ppmy.cn/devtools/150379.html

相关文章

相机小孔成像模型与透视变换

0 背景 本文用于记录小孔相机成像的数学模型推导&#xff0c;并讨论特定条件下两个相机之间看到图像的变换关系。 1 小孔成像模型 小孔成像模型如上图所示。物理世界发光点P&#xff0c;经过小孔O投影到物理成像平面&#xff0c;形成像点I’。 简易起见&#xff0c;构造虚拟成…

[Transformer] The Structure of GPT, Generative Pretrained Transformer

The Structure of Generative Pretrained Transformer Reference: The Transformer architecture of GPT models How GPT Models Work

深度学习——pytorch基础入门

一、张量 在PyTorch中&#xff0c;张量是PyTorch中最基本的数据结构。张量可以看作是一个多维数组&#xff0c;可以在GPU上加速运算。PyTorch的张量和Numpy的数组非常类似&#xff0c;但是与Numpy不同的是&#xff0c;PyTorch的张量可以自动地在GPU上进行加速计算。 PyTorch中的…

如何建立写作的护城河

如何建立写作的护城河&#xff1f;这个问题可以有答案&#xff0c;也可以没答案。 没答案是因为不存在绝对意义上的护城河&#xff0c;甚至大部分人都无法实现。有答案是针对个人和不同的期待值还是有的。 答案&#xff1a;写的足够多&#xff0c;时间足够长&#xff0c;你热爱…

【opencv】第7章 图像变换

7.1 基 于OpenCV 的 边 缘 检 测 本节中&#xff0c;我们将一起学习OpenCV 中边缘检测的各种算子和滤波器——Canny 算子、Sobel 算 子 、Laplacian 算子以及Scharr 滤波器。 7.1.1 边缘检测的一般步骤 在具体介绍之前&#xff0c;先来一起看看边缘检测的一般步骤。 1.【第…

linux: 文本编辑器vim

文本编辑器 vi的工作模式 (vim和vi一致) 进入vim的方法 方法一:输入 vim 文件名 此时左下角有 "文件名" 文件行数,字符数量 方法一: 输入 vim 新文件名 此时新建了一个文件并进入vim,左下角有 "文件名"[New File] 灰色的长方形就是光标,输入文字,左下…

MATLAB编程实用技巧深度解析

一、引言 MATLAB作为一款功能强大的科学计算和编程软件&#xff0c;在工程、科学研究等众多领域广泛应用。掌握一些实用的编程技巧&#xff0c;不仅能提高代码的执行效率&#xff0c;还能增强代码的可读性与可维护性。本文将深入探讨一系列MATLAB编程实用技巧&#xff0c;帮助读…

zkServer.sh脚本

Apache ZooKeeper 几种常见的方法&#xff1a; 一、使用 zkServer.sh 脚本&#xff1a; 最常见的启动 ZooKeeper 的方式是使用提供的 zkServer.sh 脚本。此脚本可用于管理 ZooKeeper 进程。以下是一些示例命令&#xff1a; 1. 在前台启动 ZooKeeper&#xff1a; ./zkServer.s…