【进阶篇】线程的硬件基础
文章目录
- 高速缓存
- 缓存一致性协议
- 写缓冲区和无效化队列
高速缓存
简介
高速缓存是主内存与处理器之间的硬件,其容量小于主存,但存取速率远高于主存。因此处理器在执行读写操作时,可直接和高速缓存交互,提高响应速度。
我们常见的变量名相当于内存地址,变量值相当于内存中的数据,而高速缓存相当于是为每个变量保留了一份副本。但其容量较小,不能长时间保存。
数据结构
高速缓存相当于一个容量极小的hashTable,key是内存地址,value是变量的值。从结构上来看,其由桶和缓存条目组成。其结构大致如下:
每一个缓存条目可继续划分为Tag、DataBlock、Flag三部分。DataBlock被称为缓存行,它是高速缓存与主存之间数据交换的最小单元;Tag包含了与缓存行中数据内存地址的部分信息;Flag用来表示缓存行的状态信息。
缓存命中
现在来简单说一下缓存命中的流程;当处理器在进行读取时,会先进行内存地址解码操作,解码结果包括tag、index、offset三部分数据;index相当于桶的编号,用来定位内存结构中桶的编号;tag用来定位桶对应的缓存条目,根据缓存条目的Tag进行比较;offset时缓存条目里缓存行内的位置偏移量,它用来定位一个变量在一个缓存行中存储起始位置。根据这三个来定位缓存数据,如果能找到缓存条目中的Flag,则说明缓存命中了,否则为缓存未命中。
现在处理器一般都具有多个层次的高速缓存,分为一级缓存、二级缓存、三级缓存等,一级缓存集中在cpu的内核中,访问效率极高,一般分为两部分,一部分用于存储指令,另一部分用于存储数据。离cpu越近的高速缓存,存取速率越快,但其制造成本也就越高,因此容量越小。
(图片来源百度)
缓存一致性协议
当多个线程在访问同一变量时,其中一个线程更新了该变量,需要其他线程立刻察觉到。为了解决这个问题,处理器之间需要一种通信机制------缓存一致性协议。
MESI(Modified-Exclusive-Shared-Invalid)协议是一种广为使用的缓存一致性协议。它可以保证多个线程在读共享数据时是支持并发的,但写操作是独占的。
正如它的名字一样,MESI将缓存条目状态划分为如下4种,并在此基础上定义了一组消息用于协调各个处理器读写内存的操作。
一个缓存条目中的Flag值具有以下4种可能:
状态 | 含义 | 是否与其他处理器中缓存中值一致 | 是否与主存中值一致 |
---|---|---|---|
Invalid(无效的,标记为I) | 该状态表示缓存行中不包含任何内存地址对应的值,也就是缓存未命中,它是缓存条目的初始状态。 | 否 | 否 |
Shared(共享的,标记为S | 该状态表示缓存行中存在相应内存地址的变量值的副本。且其他处理器缓存中可能也具有相同的副本。因此,如果状态为Shared,则说明其他处理器中高速缓存的值与本处理器缓存的值一样,且都为Shared。该状态表示当前处理器缓存中的值与主存一致。 | 是 | 是 |
Exclusive(独占的,标记为E) | 该状态表示缓存行存在相应内存地址的变量值的副本。且该处理器以独占的方式保留了内存地址数据的副本,其他处理器缓存中不具有该副本。该状态表示当前处理器缓存中的值与主存一致。 | 否 | 是 |
Modified(更改过的,标记为M | 该状态表示相应缓存行中存在内存地址更新后的数据。由于MESI协议只能在同一时刻有一个处理器对主存进行更新操作,因此同一时刻,多个处理器中只能有一个处理器中的缓存条目是该状态。该状态的缓存条目,其中缓存数据与主内存中的数据不一致。 | 否 | 否 |
现在来描述一下使用MESI协议的处理器是如何是先读写操作的。假设内存地址A上的数据为S可能是处理器P1和P2共享的数据。
先来看下MESI中的消息体的消息类型:
消息名称 | 消息类型 | 描述 |
---|---|---|
read | 请求 | 通知其他处理器、主存,表示当前处理器准备读取地址中的数据。该消息包含待读取数据中的内存地址 |
Read Response | 响应 | 该消息由主存或者其他处理器提供,包含被请求读取的数据。 |
Invalidate | 请求 | 通知其他处理器将对应的缓存条目状态置为I,表示删除指定内存地址的副本数据 |
Invalidate Acknowledge | 响应 | 接收到Invalidate消息的处理器必须回复该消息,表示删除了其高速缓存上相应的副本数据 |
Read Invalidate | 请求 | 该消息是由Read 和Invalidate消息组合的复合消息。告知其他处理器要更新一个数据,并且要其他处理器删除其高速缓存中相应的副本数据。 |
当P0要读取数据S时,会根据地址A找到本处理器上的缓存条目,如果P0找到的缓存条目中的Flag为M、S、E,则P0可以直接读取本处理器中地址A对应的数据S,其无需向总线中发送任何消息。如果P0找到的缓存条目为I,则说明本处理器中高速缓存不存在S的副本,此时需要向总线中发送Read消息来读取地址A的数据,其他处理器P1或者主存需要灰度Read Response以提供相应的数据。
P0接收到Read Response 时,会将其中携带的数据S存入相应的缓存行中并将缓存条目中的状态更新为S。当P0发送Respone时,P1会嗅探总线中的消息,然后从消息体中取出待读取的内存地址,找到本处理器中的缓存条目,如果状态不为I,则说明存在数据的副本,则P1构造 Read Respone消息并将数据副本所在的整块数据塞入消息中。
如果P1找到的相应缓存条目状态为M,则P1可能在向Read Response消息前将相应缓存行中的数据写入主内存,先保证主内存中的数据时最新的。发送完Read Response后,相应的缓存条目状态会更新为S。
如果P1找到的相应缓存条目状态为I,则P1不做任何处理,发送Read Response消息的可能是主内存。
当P0向地址A中写数据时,它先会根据A来找到本处理器中的缓存条目,如果缓存条目的状态为E或者M,则说明该处理器已经拥有了该数据的写权限,则P0会将数据直接写入到缓存行中,并将缓存条目更新为M。
如果P0找到的缓存条目状态不为E、M,则需要向总线中发送Invalidate消息来获取数据的所有权,其他处理器接收到Invalidate消息后会将本处理器高速缓存相应的缓存条目状态更新为I(相当于删除变量的副本)并回复Invalidate Acknowledge消息。P0必须在接收到所有处理器的消息后才能更新缓存条目。
如果P0找到的状态为S,说明P1的高速缓存可能也保留了A对应的数据副本。此时P0需要向总线中发送Invalidate消息,在接收到所有处理器回复的Invalidate Acknowledge 消息之后会将相应的缓存条目状态改为E,然后将数据写入相应的缓存条目,之后把状态更新为M。
如果P0找到的状态为I,则表示处理器不包含地址A对应的数据副本,此时P0需要向总线中发送Read Invalidate消息,P0在接收到所有处理器返回的 Read Response和Invalidate Acknowledge 消息之后会将相应的缓存条目的状态更新为E,然后将数据写入相应的缓存条目,之后把状态更新为M。
写缓冲区和无效化队列
更新中。。。
相关文章:

【进阶篇】线程的硬件基础
文章目录高速缓存缓存一致性协议写缓冲区和无效化队列高速缓存 简介 高速缓存是主内存与处理器之间的硬件,其容量小于主存,但存取速率远高于主存。因此处理器在执行读写操作时,可直接和高速缓存交互,提高响应速度。 我们常见的变…...
关于 ISP Tuning的学习,分享几点看法
关于学习,分享几点看法,欢迎讨论 。1、分阶段性的,阶梯式学习。2、带目的性的,任务式学习。3、有总结性的,输出式学习。如上3条,可以依次循环去执行,下面我以 ISP Tuning 的学习为例,…...
RocketMQ源码阅读
没有用过rocketmq,但是一直对RocketMQ的实现很感兴趣,本次阅读源码基于5.0.0 一、 nameserver 通过源码阅读发现,它的作用主要是当作一个注册中心,注册broker、topic等信息,维护topic以及broker队列的路由信息&#…...

重磅 | 小O软件新品【鲸鱼地图】发布
千呼万唤始出来.......,小O系列软件又添新品【鲸鱼地图】!!! 2023年新年伊始,小O就投入到新品研发工作中,秉承“发现地理价值”理念,为用户提供更加好用、易用的地图软件产品,经过春…...
软考高级信息系统项目管理师系列之二十五:项目合同管理
软考高级信息系统项目管理师系列之二十五:项目合同管理 一、项目合同管理内容整理一、合同管理基本概念1.项目合同管理定义2.合同的分类3.合同类型选择4.合同内容二、合同管理过程1.合同管理过程的内容2.合同签订和履行管理3.合同变更和档案管理4.合同违约索赔管理项目合同管理…...

测试开发之Django实战示例 第十三章 上线
在上一章,为其他程序与我们的Web应用交互创建了RESTful API。本章将学习如何创建生产环境让我们的网站正式上线,主要内容有:配置生产环境创建自定义中间件实现自定义管理命令1创建生产环境现在该将Django项目正式部署到生产环境中了。我们将按…...
python实战应用讲解-【语法基础篇】Python中的数值类型(附示例代码)
目录 前言 数值类型 十六进制、八进制和二进制 Python 数值类型转换 数值和表达式 前言...

Git常用命令以及如何在IDEA中使用Git
前言Git是一个分布式版本控制工具,主要用于管理开发过程中的源代码文件(Java类、xml文件、html页面等)。Git在管理文件过程中会记录日志,方便回退到历史版本;Git存在分支的概念,一个项目可以有多个分支&…...

音乐播放器-- 以及数据库数据存储
运行环境 : java1.8 数据库以及代码编写工具 : sqlserver -- mysql 也可以 工具 eclipse 编码gbk窗体 : Swing使用了jaudiotagger 进行了音乐处理 图片展示 ----- 空闲时间 做出来玩的项目 部分功能还没有完善 完善了的功能 音乐 /// 主页 &a…...

[JAVA安全]Spring Messaging之CVE-2018-1270
漏洞简介 Spring 框架中通过spring-messaging 模块来实现 STOMP (Simple Text-Orientated Messaging Protocol),STOMP是一种封装 WebSocket的简单消息协议。攻击者可以通过建立WebSocket连接并发送一条消息造成远程代码执行, spring-messagin…...

CAN通信笔记-位时间、Tq及采样点同步
本文框架1.前言2. 位时间2.1 位时间定义2.2 位时间计算3. Tq3.1 Tq的计算3.1.1 举个例子3.2 位时间与Tq的换算4. 采样点同步4.1 硬同步4.2 重同步4.2.1 延长PBS1的重同步4.2.2 缩短PBS2的重同步1.前言 本篇记录些关于CAN的一些学习笔记,说实话CAN协议发展的已经非常…...

玩转 Kubernetes 配置管理:ConfigMap 和 Secret 实战演示
目录一、简介二、ConfigMap2.1 基于目录创建 ConfigMap2.2 基于文件创建 ConfigMap2.3 从环境文件创建 ConfigMap2.4 定义从文件创建 ConfigMap 时要使用的键2.5 根据字符串创建 ConfigMap三、Secret3.1 基于文件创建Secret3.2 基于字符串创建Secret3.3 yaml文件方式创建secret…...

Kubernetes
一、 kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不能为应用程序定义…...

从零开始 verilog 以太网交换机(三)MAC发送控制器的设计与实现
从零开始 verilog 以太网交换机(三)MAC发送控制器的设计与实现 🔈声明: 😃博主主页:王_嘻嘻的CSDN主页 🧨 从零开始 verilog 以太网交换机系列专栏:点击这里 🔑未经作者允…...

使用vector<char>作为输入缓冲区
一、引言 当我们编写代码:实现网络接收、读取文件内容等功能时,我们往往要在内存中开辟一个输入缓冲区(又名:input buffer/读缓冲区)来存贮接收到的数据。在C里面我们可以用如下方法开辟输入缓冲区。 ①使用C语言中的数组&#x…...
自己在网站搭建用到的一些网站
背景 以后可能很少做网站类的项目了,所以做个简单总结,把自己的一些经历和一些小工具做个记录 域名和主机 https://www.godaddy.com/zh-sg, 我之前的基本都是国际会议型的网站,所以就在gadaddy上买了主机和域名。目标群体在国内可以考虑腾…...
XLSReadWriteII5 Color 颜色l的调用和使用
XLSReadWriteII5 Color 颜色l的调用和使用 一、色彩三原色 自然界,颜色是由红、绿、蓝三色组成,人眼的可见的颜色,可以通过红、绿、蓝三色按照不同的比例合成产生。 任意一种颜色由这三种原色按照一定的比例混合出来。 二、Windows系…...

RT-Thread SP使用教程
RT-Thread SPI 使用教程 实验环境使用的是正点原子的潘多拉开发板。 SPI从机设备使用的是BMP280温湿度大气压传感器。 使用RT-Thread Studio搭建基础功能。 1. 创建工程 使用RT-Thread Studio IDE创建芯片级的工程。创建完成后,可以直接编译下载进行测试。 2.…...
LeetCode 2363. 合并相似的物品
给你两个二维整数数组 items1 和 items2 ,表示两个物品集合。每个数组 items 有以下特质: items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 ,weighti 表示第 i 件物品的 重量 。 items 中每件物品的价值都是 唯一的 。 请你…...

numpy 中常用的数据保存、fmt多个参数
在经常性读取大量的数值文件时(比如深度学习训练数据),可以考虑现将数据存储为Numpy格式,然后直接使用Numpy去读取,速度相比为转化前快很多 一、保存为二进制文件(.npy/.npz) (1)numpy.save(file, arr, allow_pickleTrue, fix_importsTrue) file:文件名…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

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

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...

【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...

在MobaXterm 打开图形工具firefox
目录 1.安装 X 服务器软件 2.服务器端配置 3.客户端配置 4.安装并打开 Firefox 1.安装 X 服务器软件 Centos系统 # CentOS/RHEL 7 及之前(YUM) sudo yum install xorg-x11-server-Xorg xorg-x11-xinit xorg-x11-utils mesa-libEGL mesa-libGL mesa-…...