无锁编程——从CPU缓存一致性讲到内存模型(1)
一.前言
1.什么是有锁编程,什么是无锁编程?
在编程中,特别是在并发编程的上下文中,“无锁”和“有锁”是描述线程同步和资源访问控制的两种不同策略。
有锁(Locked):
有锁编程是指使用锁(例如互斥锁、信号量等)来控制对共享资源的访问。在有锁策略中,线程必须在执行关键部分的代码前获得锁,以确保同一时间只有一个线程可以访问和修改共享资源。当线程完成对共享资源的操作后,它释放锁,使得其他线程可以接着访问资源。
特点包括:
线程安全:通过锁可以防止多个线程同时访问共享资源,避免竞争条件。
阻塞:线程在尝试获取一个已被其他线程持有的锁时,将会被阻塞,直到锁被释放。
开销:锁的获取和释放涉及操作系统层面的上下文切换,可能会导致较大的性能开销。
死锁:不正确的锁使用可能导致死锁,即两个或多个线程永久性地阻塞,等待彼此释放锁。
无锁(Lock-free):
无锁编程是一种不依赖于传统锁机制来控制共享资源访问的并发编程技术。无锁编程通常利用原子操作来确保即使在多个线程同时访问时,共享资源也能保持一致性。
那什么原子操作?
原子操作是指不可被中断的一个或一系列操作。它通过硬件支持来保证操作的原子性,通常使用特殊的CPU指令来实现。这些指令能够在单个步骤中完成读取-修改-写入的操作,而不会被其他线程中断。
上面提到的特殊指令->能够完成读取-修改-写入操作,指的是CAS(比较后交换技术)。为什么提到它,有什么用处?
这就要说到现代计算机的存储结构以及解决提升效率带来的一些硬件设备。
二.理解无锁编程需要的知识
1.存储结构
可以看出L1和L2是每个核心都会有的。L3是一个处理器下的核心共有的。
主存(常规语境下所指的内存)是所有核心共有的。
越往下容量越大,同时读取速度越慢。
Cpu访问缓存的时候会有一个最小的读取单位,叫做cache line,一般是64个字节。
那么问题来了。为什么需要cache line ?(缓存),为什么这么设计?
因为:减少内存访问延迟:CPU的运行速度远远高于主内存的访问速度。Cache Line通过提供一个小而快速的存储,使得CPU能够更快地访问经常使用的数据和指令,从而减少了因等待内存访问而造成的延迟。
提高数据访问效率:由于数据访问通常具有空间局部性(连续的数据被一起访问),Cache Line作为一个数据块单位,可以一次性将多个连续的数据加载到缓存中。这样,当CPU访问其中一个数据时,很可能接下来的数据已经在缓存中了,从而提高了数据访问的效率。
带宽优化:与内存接口相比,CPU和缓存之间的数据带宽要宽得多。通过Cache Line,可以更有效地利用这带宽,因为每次传输都是传输一个数据块,而不是单个字节。
实现预取和并行处理:现代CPU通常具有预取机制,能够预测哪些数据将会被访问,并提前将数据加载到Cache中。Cache Line作为一个块单位,使得预取更加有效。同时,多核CPU可以利用Cache Line来并行处理数据,提高多任务处理的效率。
减少总线压力:如果没有缓存,CPU每次读写数据都要直接与内存通信,这会极大地增加总线上的数据流量。Cache Line允许CPU在大多数情况下与缓存而不是内存进行通信,从而减少了总线的压力。
提升能效:由于Cache Line减少了内存访问次数,因此也降低了内存功耗,整体上提升了系统的能效。
这种由cpu写到缓存而不是内存的策略叫做写回策略。
三.写回策略
写直达策略:每次写操作会写到缓存中,也会写到内存中。写性能会很低,现代计算机很少使用了。
写回策略:尽量把数据存储到缓存之中,如果能写到缓存之中就避免写道内存中。
是否命中缓存:是指之前的缓存中是否存有这个变量。
脏数据:缓存与内存不一致,或缓存有内存无的数据被标记为脏数据。
写数据的时候如果没有命中缓存,就利用LRU策略寻找到缓存中使用最少的区域,如果这块区域有数据并且是脏数据,那么将这块区域的数据刷入内存中。如果不是直接写入缓存。
读数据的时候如果没有命中缓存,先把数据从内存读入缓存,cpu再进行使用数据。
写回策略带来什么问题?
现代计算机结构有多个核心对应多个缓存,核心间共享的变量在不同的核心的缓存里内容不一样的问题。
如何解决?
四.MESI一致性协议
通过实现MESI一致性协议解决。他的内容及流程如下:
缓存一致性协议是确保多处理器系统中各个处理器的缓存数据一致性的机制。让我们详细讨论一下最常见的MESI(Modified, Exclusive, Shared, Invalid)协议的操作流程:
1. MESI协议状态:
- Modified (M): 数据被修改,只在当前缓存中有效,与主存不一致。
- Exclusive (E): 数据只在当前缓存中,未被修改,与主存一致。
- Shared (S): 数据可能在多个缓存中存在,与主存一致。
- Invalid (I): 缓存行无效。
2. 基本操作流程:
a. 读操作:
- 缓存未命中时:
* 如果其他缓存有此数据(M或E状态),该缓存需先将数据写回主存。
* 从主存读取数据,标记为S状态(如果其他缓存也有)或E状态(如果独占)。
- 缓存命中时:
* 如果是M、E或S状态,直接读取。
* 如果是I状态,按缓存未命中处理。
b. 写操作:
- 缓存未命中时:
* 如果其他缓存有此数据,需先使其无效。
* 从主存读取数据,进行修改,标记为M状态。
- 缓存命中时:
* 如果是M状态,直接写入。
* 如果是E状态,修改并变为M状态。
* 如果是S状态,需先使其他缓存中的副本无效,然后修改并变为M状态。
* 如果是I状态,按缓存未命中处理。
3. 状态转换:
- I → E: 读取未被其他缓存持有的数据。
- I → S: 读取被其他缓存共享的数据。
- E → M: 修改独占的数据。
- S → M: 修改共享的数据(需先使其他缓存副本无效)。
- M → I, E → I, S → I: 其他处理器写入该数据。
4. 总线操作:
- Read: 请求读取数据。
- Read with Intent to Modify (RWITM): 请求读取并修改数据。
- Invalidate: 使其他缓存中的副本无效。
- Writeback: 将修改后的数据写回主存。
5. 协议执行流程:
a. 处理器发出内存访问请求。
b. 检查本地缓存状态。
c. 根据状态和操作类型,可能需要发起总线事务。
d. 其他处理器监听总线,根据需要更新自己的缓存状态。
e. 完成数据访问或修改。
上面我们提到了CAS,与缓存一致性的关系?
五.CAS
CAS:是实现原子操作和无锁数据结构的基础。
function CAS(M, A, B) isif M == AM ← Breturn trueelsereturn false
它是一种原子操作,它比较内存位置的内容与给定值,只有在相同的情况下,才会将该内存位置的内容修改为新的给定值。
CAS与缓存一致性的关系,就是需要CAS在写回策略的环境中维护正确性和高效性,这需要硬件层面的支持和软件的安全编程。
六.内存序和内存屏障
C++中原子操作往往有一个参数是规定内存序,用于指导编译器进行优化,用于指导cpu进行指令重排。可以解决两个问题,一是变量更新是否能马上被其他线程看到,二是代码顺序性的问题。
那么问题来了,为什么会有内存序问题?
因为编译器和cpu会在判断代码顺序不影响程序的情况下,有可能会重排相邻的代码执行顺序。比如一个线程锁住了一块内存空间,另一个线程无法操作那块内存空间,这项操作之后的操作并不刚需这块内存空间,这时候可能会重排先往后执行。这是为了提升整个系统的性能,但有时我们要求一定要按某个顺序执行,那么就有时候就不允许重排操作。
内存序和内存屏障是为了解决现代计算机系统中由于硬件优化和多核处理器引起的内存访问复杂性问题
内存序:指定了内存操作的可见性和顺序性规则。
内存屏障:用于强制执行特定的内存操作顺序的硬件指令。
内存序和内存屏障的关系:
- 内存序是高级抽象,定义了操作的语义。
- 内存屏障是底层实现机制,用于实现内存序。
C++11原子变量内存序的相关参数
见:std::memory_order - cppreference.com std内存屏障API,
相关文章:

无锁编程——从CPU缓存一致性讲到内存模型(1)
一.前言 1.什么是有锁编程,什么是无锁编程? 在编程中,特别是在并发编程的上下文中,“无锁”和“有锁”是描述线程同步和资源访问控制的两种不同策略。有锁(Locked): 有锁编程是指使用锁(例如互…...

C++编程(七)继承
文章目录 一、继承(一)概念(二)语法格式(三)通过子类访问父类中的成员1. 类内2. 类外 (四)继承中的特殊成员函数1. 构造函数2. 析构函数3. 拷贝构造函数4. 拷贝赋值函数 二、多重继承…...

【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering
【ACM_2023】3D Gaussian Splatting for Real-Time Radiance Field Rendering 一、前言Abstract1 INTRODUCTION2 RELATED WORK2.1 Traditional Scene Reconstruction and Rendering2.2 Neural Rendering and Radiance Fields2.3 Point-Based Rendering and Radiance Fields 3 O…...

【TB作品】atmega16 计算器,ATMEGA16单片机,Proteus仿真
实验报告:基于ATmega16单片机的简易计算器设计 1. 实验背景 计算器是日常生活和工作中不可或缺的工具,通过按键输入即可实现基本的四则运算。通过本实验,我们将利用ATmega16单片机、矩阵键盘和LCD1602显示屏,设计并实现一个简易…...

C++的IO流操作
文章目录 C语言的输入与输出流是什么CIO流C标准IO流C文件IO流二进制读写文本读写 stringstream的简单介绍 C语言的输入与输出 C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf()与printf()。 scanf(): 从标准输入设备(键盘)读取数据,并将值存放…...
MacOS升级指定Python版本的pip
场景: 系统默认是Python2.7,已经通过brew install python3.11 python3.12安装了多个版本的Python 执行:pip --version pip 24.1 from /Users/mac10.12/Library/Python/3.11/lib/python/site-packages/pip (python 3.11) 用的是Python3.11…...

音频Balance源码总结
音频Balance源码总结 何为音频Balance? 顾名思义,Balance及平衡,平衡也就是涉及多方,音频左右甚至四通道,调节所有通道的音量比,使用户在空间内听到各个通道的音频大小不一,好似置身于真实环境…...
CesiumJS【Basic】- #043 绘制脉冲线(Entity方式)- 需要自定义着色器
文章目录 绘制脉冲线(Entity方式)- 需要自定义着色器1 目标2 代码2.1 main.ts3 资源文件绘制脉冲线(Entity方式)- 需要自定义着色器 1 目标 使用Entity方式绘制脉冲线 2 代码 2.1 main.ts import * as Cesium from cesium;const viewer = new Cesium.Viewer(cesiumCont…...

Linux命令 wc(word count)-l(lines)用于统计文件中的行数。
文章目录 1、wc -l2、实战3、wc --help 1、wc -l 在命令 wc -l 中,-l 的英文全称是 lines。这个选项用于指定 wc(word count,单词计数)命令来统计文件的行数。 例如,当你运行 wc -l load_user_100w_sort.sql 时&…...

数据结构 - C/C++ - 链表
目录 结构特性 内存布局 结构样式 结构拓展 单链表 结构定义 节点关联 插入节点 删除节点 常见操作 双链表 环链表 结构容器 结构设计 结构特性 线性结构的存储方式 顺序存储 - 数组 链式存储 - 链表 线性结构的链式存储是通过任意的存储单元来存储线性…...

sheng的学习笔记-AI-高斯混合模型(GMM)
AI目录:sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识: 聚类,可参考 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 EM算法,可参考 sheng的学习笔记-AI-EM算法-CSDN博客 贝叶斯,可参考 sheng的学习笔记-AI-…...

OFDM的缺点与关键技术
子载波间干扰英文简写ICI,ICI可能由各种原因引起 在多径信道中,CP小于最大附加时延时收发系统载波频率偏差和采样偏差收发系统相对移动,存在多普勒频移 ICI是制约OFDM系统性能的主要重要因素之一 对频率偏差敏感----->同步技术࿰…...

电脑录音软件哪个好?7款录制音频工具大盘点,赶快学起来!(2024)
也许你渴望提取你最喜欢的节目的背景音乐,或者你希望录制自己的声音制作教程。如果是这样,你就需要一款优秀的电脑录音软件,来帮助你捕捉任何你想要的声音,而且不会损失音质。目前市场上存在着大量的录制音频工具,面对…...
【Android面试八股文】你说你使用Leakcanary进行内存泄漏检测,那你能说一说Leakcanary的原理吗?
文章目录 一、 Java四大引用二、 LeakCanary示例工作机制注意事项三、 Leakcanary的原理四、 Leakcanary的源码分析LeakCanary#Install创建RefWatcherAndroidRefWatcherBuilder#buildAndInstall监听Activity的引用 : ActivityRefWatcher检查引用Dump Heap解析hprof定位泄露的引…...

蒂升电梯职业性格和Verify认知能力SHL测评答题攻略及薪资待遇解密!
一、蒂升电梯职业性格和认知能力测评考什么 您好!蒂升电梯公司邀请您参加的OPQ职业性格测评和Verify认知能力测评是两种常见的评估工具,用于帮助了解个人的职场性格特点和认知能力。 OPQ职业性格测评 这是一种性格测试,通常用于评估个人在…...

window上部署sql server改动端口、和sqlserver的一些还原、批量插入存储过程的命令
1.端口的查看和启动 --windows上安装上sql server数据库后,搜索界面搜索sql,会出现配置管理器,点击进入 --进入后再次选择配置管理器 2. sqlserver数据库还原图形化 sqlserver还原数据库时会使数据库进入一个restore的还原状态,…...

【单片机与嵌入式】stm32串口通信入门
一、串口通信/协议 (一)串口通信简介 串口通信是一种通过串行传输方式在电子设备之间进行数据交换的通信方式。它通常涉及两条线(一条用于发送数据,一条用于接收数据),适用于各种设备,从微控制…...
启动Redis服务器
名人说:一点浩然气,千里快哉风。 ——苏轼 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、在 Linux 或 macOS 上启动 Redis二、在 Windows 上启动 Redis三、配置 Redis 为服务启动&…...
uniapp中使用threejs加载几何体
我的建议是使用这个库 https://github.com/deepkolos/three-platformize 为什么?我试了uniapp推荐的和threejs-miniprogram这个小程序官方库,都加载不出来我的obj模型。所有我推荐不要用obj模型最好,挺多都支持GLTF模型的,但是我不…...
【SQL注入】 数据库基础
MySQL中的库名 information_schema(信息库)—— 保存其他数据库里所有信息(数据库名、表、字段的数据类型/访问权限) mysql—— 存储用户名 密码 host performance_schema——内存数据库 数据放在内存中直接操作的数据库 sys—…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...