计算机操作系统学习笔记(3)——CPU缓存一致性

简介: 计算机操作系统学习笔记(3)——CPU缓存一致性

一、CPU Cache写回内存

之前说的CPU Cache缓存块实际分为:头标志Tag和数据块Data Block

前面说的直接映射,取模运算有可能发生冲突,发生了冲突就用Tag去标记。组标记(Tag)。这个组标记会记录当前 CPU Line 中存储的数据对应的内存块,我们可以⽤这个组标记来区分不同的内存块。

Cache里的数据总要写回内存的,那在什么时机才把 Cache 中的数据写回到内存呢?

这里有2种方案:写直达和写回
写直达:写直达法很直观,也很简单,把数据同时写⼊内存和 Cache 中,⽆论数据在不在 Cache ⾥⾯,每次写操作都会写回到内存,这样写操作将会花费⼤量的时间,⽆疑性能会受到很⼤的影响。
写回:在写回机制中,如果当发⽣写操作时,数据所对应的 Cache Block ⾥存放的是「别的内存地址的数据」的话,就要检查这个 Cache Block ⾥的数据有没有被标记为脏的,如果是脏的话,我们就要把这个 
Cache Block ⾥的数据写回到内存,然后再把当前要写⼊的数据,写⼊到这个 Cache Block ⾥,同时也把它标记为脏的;。这样的好处是,如果我们⼤量的操作都能够命中缓存,那么⼤部分时间⾥ CPU 都不需要读写
内存,⾃然性能相⽐写直达会⾼很多。
脏说明这个数据被更新了,说白了写回策略其实就是操作一个变量,直到换成了操作其他变量才更新

二、何为CPU缓存一致性问题?

举个例子:如果一个CPU有2个核心A和B,他们都操作共同的变量 i(初始值为 0 )。

这时如果 A 号核⼼执⾏了 i++ 语句的时候,为了考虑性能,使⽤了我们前⾯所说的写回策略,先把值为 1 的执⾏结果写⼊到 L1/L2 Cache 中,然后把 L1/L2 Cache 中对应的 Block标记为脏的,这个时候数据其实没有被同步到内存中的,因为写回策略,只有在 A 号核⼼中的这个 Cache Block 要被替换的时候,数据才会写⼊到内存⾥。


如果这时 B 号核⼼尝试从内存读取 i 变量的值,则读到的将会是错误的值,因为刚才A 号核⼼更新 i 值还没写⼊到内存中,内存中的值还依然是 0。这个就是所谓的缓存⼀致性问

题,A 号核⼼和 B 号核⼼的缓存,在这个时候是不⼀致,从⽽会导致执⾏结果的错误。

三、怎么解决缓存一致性问题?

要保证缓存一致性问题,要保证2点: 写传播(Wreite Propagation)和 事务的串形化(Transaction Serialization)

事务串形化

解释一下,事务串行化:

假设我们有⼀个含有 4 个核⼼的 CPU,这 4 个核⼼都操作共同的变量 i(初始值为 0 )。A号核⼼先把 i 值变为 100,⽽此时同⼀时间,B 号核⼼先把 i 值变为 200,这⾥两个修改,都
会「传播」到 C 和 D 号核⼼。那么问题就来了,C 号核⼼先收到了 A 号核⼼更新数据的事件,再收到 B 号核⼼更新数据的事件,因此 C 号核⼼看到的变量 i 是先变成 100,后变成 200。
⽽如果 D 号核⼼收到的事件是反过来的,则 D 号核⼼看到的是变量 i 先变成 200,再变成100,虽然是做到了写传播,但是各个 Cache ⾥⾯的数据还是不⼀致的。所以,我们要保证 C 号核⼼和 D 号核⼼都能看到相同顺序的数据变化,⽐如变量 i 都是先变
成 100,再变成 200,这样的过程就是事务的串形化。

写传播

写传播很容易就理解,当某个核⼼在 Cache 更新了数据,就需要同步到其他核⼼的Cache ⾥。


写传播就是写传播最常⻅实现的⽅式是总线嗅探(Bus Snooping)。说白了就类似一个消息队列,其他缓存去监听,数据被修改了,操作那个数据都缓存发条消息,其他缓存就都知道了。


可以发现,总线嗅探⽅法很简单, CPU 需要每时每刻监听总线上的⼀切活动,但是不管别的核⼼的 Cache 是否缓存相同的数据,都需要发出⼀个⼴播事件,这⽆疑会加重总线的负载。


总线嗅探并不能保证事务串形化。


于是,有⼀个协议基于总线嗅探机制实现了事务串形化,也⽤状态机机制降低了总线带宽压⼒,这个协议就是 MESI 协议,这个协议就做到了 CPU 缓存⼀致性。

四、MESI 协议

MESI 协议其实是 4 个状态单词的开头字⺟缩写,这四个状态来标记 Cache Line 四个不同的状态,而这些状态是通过总线广播出去的,所以说是基于总线嗅探的,分别是:

Modified,已修改
Exclusive,独占
Shared,共享
Invalidated,已失效

「已修改」状态就是我们前⾯提到的脏标记,代表该 Cache Block 上的数据已经被更新过,但是还没有写到内存⾥。⽽「已失效」状态,表示的是这个 Cache Block ⾥的数据已经失效
了,不可以读取该状态的数据。
「独占」和「共享」状态都代表 Cache Block ⾥的数据是⼲净的,也就是说,这个时候
Cache Block ⾥的数据和内存⾥⾯的数据是⼀致性的。「独占」和「共享」的差别在于,独占状态的时候,数据只存储在⼀个 CPU 核⼼的 Cache
⾥,⽽其他 CPU 核⼼的 Cache 没有该数据。这个时候,如果要向独占的 Cache 写数据,就可以直接⾃由地写⼊,⽽不需要通知其他 CPU 核⼼,因为只有你这有这个数据,就不存在缓
存⼀致性的问题了,于是就可以随便操作该数据。另外,在「独占」状态下的数据,如果有其他核⼼从内存读取了相同的数据到各⾃的 Cache
,那么这个时候,独占状态下的数据就会变成共享状态。那么,「共享」状态代表着相同的数据在多个 CPU 核⼼的 Cache ⾥都有,所以当我们要更新 Cache ⾥⾯的数据的时候,不能直接修改,⽽是要先向所有的其他 CPU 核⼼⼴播⼀个请
求,要求先把其他核⼼的 Cache 中对应的 Cache Line 标记为「⽆效」状态,然后再更新当前 Cache ⾥⾯的数据。
我们举个具体的例⼦来看看这四个状态的转换:
1. 当 A 号 CPU 核⼼从内存读取变量 i 的值,数据被缓存在 A 号 CPU 核⼼⾃⼰的 Cache ⾥⾯,此时其他 CPU 核⼼的 Cache 没有缓存该数据,于是标记 Cache Line 状态为「独占」,
此时其 Cache 中的数据与内存是⼀致的;
2. 然后 B 号 CPU 核⼼也从内存读取了变量 i 的值,此时会发送消息给其他 CPU 核⼼,由
于 A 号 CPU 核⼼已经缓存了该数据,所以会把数据返回给 B 号 CPU 核⼼。在这个时候, A 和 B 核⼼缓存了相同的数据,Cache Line 的状态就会变成「共享」,并且其Cache 中的数据与内存也是⼀致的;
3. 当 A 号 CPU 核⼼要修改 Cache 中 i 变量的值,发现数据对应的 Cache Line 的状态是共享状态,则要向所有的其他 CPU 核⼼⼴播⼀个请求,要求先把其他核⼼的 Cache 中对应的 Cache Line 标记为「⽆效」状态,然后 A 号 CPU 核⼼才更新 Cache ⾥⾯的数据,
同时标记 Cache Line 为「已修改」状态,此时 Cache 中的数据就与内存不⼀致了。
4. 如果 A 号 CPU 核⼼「继续」修改 Cache 中 i 变量的值,由于此时的 Cache Line 是「已
修改」状态,因此不需要给其他 CPU 核⼼发送消息,直接更新数据即可。
5. 如果 A 号 CPU 核⼼的 Cache ⾥的 i 变量对应的 Cache Line 要被「替换」,发现Cache Line 状态是「已修改」状态,就会在替换前先把数据同步到内存。所以,可以发现当 Cache Line 状态是「已修改」或者「独占」状态时,修改更新其数据不需
要发送⼴播给其他 CPU 核⼼,这在⼀定程度上减少了总线带宽压⼒。

对于在「已修改」或者「独占」状态的 Cache Line,修改更新其数据不需要发送⼴播给其他 CPU 核⼼。

这个MESI,我这里只是简诉,Java中的volatile保证的可见性,底层的原理就是依靠于MESI,建议这个协议还是有必要了解下。

目录
相关文章
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
Android开发 Windows
这是我设想的免重启操作系统的状态下更新通用计算机、嵌入式操作系统的软件设计思路
本方案提出了一种名为slfm的软件系统,旨在实现通用计算机及嵌入式系统在不重启状态下完成操作系统更新。其核心机制是通过构建独立于原系统的运行环境(slfm Recovery与The Tube),在高权限模式下进行系统文件更新与切换,确保更新过程中设备持续运行,适用于普通设备与不可中断服务的关键系统(如医疗、服务器等)。同时具备失败回滚、数据同步、权限隔离等功能,提升系统更新的安全性与可用性。
|
缓存 安全 Linux
Linux系统查看操作系统版本信息、CPU信息、模块信息
在Linux系统中,常用命令可帮助用户查看操作系统版本、CPU信息和模块信息
3986 23
|
人工智能 并行计算 安全
用户实操:如何以龙蜥操作系统为底座在 CPU 上运行 DeepSeek-R1
介绍如何在 CPU 上使用 llama.cpp 推理 671B 版本的 DeepSeek R1,以及实际效果。
|
存储 安全 固态存储
计算机启动:从插上电源到操作系统启动的全过程
当我们插上电源,计算机从休眠状态苏醒,直至操作系统完全启动,这一系列复杂的过程涉及到硬件和软件的多个层面。本文将详细解析计算机插上电源后操作系统所做的工作,揭示这一过程的技术细节。
1454 6
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
存储 算法 网络协议
了解操作系统的基本原理和常见操作,提高计算机使用效率
了解操作系统的基本原理和常见操作,提高计算机使用效率
505 4
|
运维 安全 Linux
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
计算机架构“寒武纪爆发”,操作系统进化迸发中国浪潮
|
缓存 NoSQL Redis
【Azure Redis 缓存】Redis的指标显示CPU为70%,而Service Load却达到了100%。这两个指标意义的解释及如何缓解呢?
【Azure Redis 缓存】Redis的指标显示CPU为70%,而Service Load却达到了100%。这两个指标意义的解释及如何缓解呢?
318 0
|
11月前
|
缓存 人工智能 算法
不同业务怎么选服务器?CPU / 内存 / 带宽配置表
本文详解了服务器三大核心配置——CPU、内存、带宽,帮助读者快速理解服务器性能原理。结合不同业务场景,如个人博客、电商、数据库、直播等,提供配置选择建议,并强调合理搭配的重要性,避免资源浪费或瓶颈限制。内容实用,适合初学者和业务选型参考。
1572 0

热门文章

最新文章

推荐镜像

更多