专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

一文读懂CPU缓存一致性的实现

  话不多说,本文大纲
  CPUCache的数据写入
  随着时间的推移,CPU和内存的访问性能相差越来越大,于是就在CPU内部嵌入了CPUCache(高速缓存),CPUCache离CPU核心相当近,因此它的访问速度是很快的,于是它充当了CPU与内存之间的缓存角色。
  CPUCache通常分为三级缓存:L1Cache、L2Cache、L3Cache,级别越低的离CPU核心越近,访问速度也快,但是存储容量相对就会越小。其中,在多核心的CPU里,每个核心都有各自的L1L2Cache,而L3Cache是所有核心共享使用的。
  我们先简单了解下CPUCache的结构,CPUCache是由很多个CacheLine组成的,CPULine是CPU从内存读取数据的基本单位,而CPULine是由各种标志(Tag)数据块(DataBlock)组成,你可以在下图清晰的看到:
  我们当然期望CPU读取数据的时候,都是尽可能地从CPUCache中读取,而不是每一次都要从内存中获取数据。所以,身为程序员,我们要尽可能写出缓存命中率高的代码,这样就有效提高程序的性能,具体的做法,你可以参考我上一篇文章如何写出让CPU跑得更快的代码?(opensnewwindow)
  事实上,数据不光是只有读操作,还有写操作,那么如果数据写入Cache之后,内存与Cache相对应的数据将会不同,这种情况下Cache和内存数据都不一致了,于是我们肯定是要把Cache中的数据同步到内存里的。
  问题来了,那在什么时机才把Cache中的数据写回到内存呢?为了应对这个问题,下面介绍两种针对写入数据的方法:写直达(WriteThrough)写回(WriteBack)
  写直达
  保持内存与Cache一致性最简单的方式是,把数据同时写入内存和Cache中,这种方法称为写直达(WriteThrough)。
  在这个方法里,写入前会先判断数据是否已经在CPUCache里面了:如果数据已经在Cache里面,先将数据更新到Cache里面,再写入到内存里面;如果数据没有在Cache里面,就直接把数据更新到内存里面。
  写直达法很直观,也很简单,但是问题明显,无论数据在不在Cache里面,每次写操作都会写回到内存,这样写操作将会花费大量的时间,无疑性能会受到很大的影响。
  写回
  既然写直达由于每次写操作都会把数据写回到内存,而导致影响性能,于是为了要减少数据写回内存的频率,就出现了写回(WriteBack)的方法。
  在写回机制中,当发生写操作时,新的数据仅仅被写入CacheBlock里,只有当修改过的CacheBlock被替换时才需要写到内存中,减少了数据写回内存的频率,这样便可以提高系统的性能。
  那具体如何做到的呢?下面来详细说一下:如果当发生写操作时,数据已经在CPUCache里的话,则把数据更新到CPUCache里,同时标记CPUCache里的这个CacheBlock为脏(Dirty)的,这个脏的标记代表这个时候,我们CPUCache里面的这个CacheBlock的数据和内存是不一致的,这种情况是不用把数据写到内存里的;如果当发生写操作时,数据所对应的CacheBlock里存放的是别的内存地址的数据的话,就要检查这个CacheBlock里的数据有没有被标记为脏的:如果是脏的话,我们就要把这个CacheBlock里的数据写回到内存,然后再把当前要写入的数据,先从内存读入到CacheBlock里(注意,这一步不是没用的,具体为什么要这一步,可以看这个回答(opensnewwindow)),然后再把当前要写入的数据写入到CacheBlock,最后也把它标记为脏的;如果不是脏的话,把当前要写入的数据先从内存读入到CacheBlock里,接着将数据写入到这个CacheBlock里,然后再把这个CacheBlock标记为脏的就好了。
  可以发现写回这个方法,在把数据写入到Cache的时候,只有在缓存不命中,同时数据对应的Cache中的CacheBlock为脏标记的情况下,才会将数据写到内存中,而在缓存命中的情况下,则在写入后Cache后,只需把该数据对应的CacheBlock标记为脏即可,而不用写到内存里。
  这样的好处是,如果我们大量的操作都能够命中缓存,那么大部分时间里CPU都不需要读写内存,自然性能相比写直达会高很多。
  为什么缓存没命中时,还要定位CacheBlock?这是因为此时是要判断数据即将写入到cacheblock里的位置,是否被其他数据占用了此位置,如果这个其他数据是脏数据,那么就要帮忙把它写回到内存。
  CPU缓存与内存使用写回机制的流程图如下,左半部分就是读操作的流程,右半部分就是写操作的流程,也就是我们上面讲的内容。
  缓存一致性问题
  现在CPU都是多核的,由于L1L2Cache是多个核心各自独有的,那么会带来多核心的缓存一致性(CacheCoherence)的问题,如果不能保证缓存一致性的问题,就可能造成结果错误。
  那缓存一致性的问题具体是怎么发生的呢?我们以一个含有两个核心的CPU作为例子看一看。
  假设A号核心和B号核心同时运行两个线程,都操作共同的变量i(初始值为0)。
  这时如果A号核心执行了i语句的时候,为了考虑性能,使用了我们前面所说的写回策略,先把值为1的执行结果写入到L1L2Cache中,然后把L1L2Cache中对应的Block标记为脏的,这个时候数据其实没有被同步到内存中的,因为写回策略,只有在A号核心中的这个CacheBlock要被替换的时候,数据才会写入到内存里。
  如果这时旁边的B号核心尝试从内存读取i变量的值,则读到的将会是错误的值,因为刚才A号核心更新i值还没写入到内存中,内存中的值还依然是0。这个就是所谓的缓存一致性问题,A号核心和B号核心的缓存,在这个时候是不一致,从而会导致执行结果的错误。
  那么,要解决这一问题,就需要一种机制,来同步两个不同核心里面的缓存数据。要实现的这个机制的话,要保证做到下面这2点:第一点,某个CPU核心里的Cache数据更新时,必须要传播到其他核心的Cache,这个称为写传播(WritePropagation);第二点,某个CPU核心里对数据的操作顺序,必须在其他核心看起来顺序是一样的,这个称为事务的串行化(TransactionSerialization)。
  第一点写传播很容易就理解,当某个核心在Cache更新了数据,就需要同步到其他核心的Cache里。而对于第二点事务的串行化,我们举个例子来理解它。
  假设我们有一个含有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,这样的过程就是事务的串行化。
  要实现事务串行化,要做到2点:CPU核心对于Cache中数据的操作,需要同步给其他CPU核心;要引入锁的概念,如果两个CPU核心里有相同数据的Cache,那么对于这个Cache数据的更新,只有拿到了锁,才能进行对应的数据更新。
  那接下来我们看看,写传播和事务串行化具体是用什么技术实现的。
  总线嗅探
  写传播的原则就是当某个CPU核心更新了Cache中的数据,要把该事件广播通知到其他核心。最常见实现的方式是总线嗅探(BusSnooping)。
  我还是以前面的i变量例子来说明总线嗅探的工作机制,当A号CPU核心修改了L1Cache中i变量的值,通过总线把这个事件广播通知给其他所有的核心,然后每个CPU核心都会监听总线上的广播事件,并检查是否有相同的数据在自己的L1Cache里面,如果B号CPU核心的L1Cache中有该数据,那么也需要把该数据更新到自己的L1Cache。
  可以发现,总线嗅探方法很简单,CPU需要每时每刻监听总线上的一切活动,但是不管别的核心的Cache是否缓存相同的数据,都需要发出一个广播事件,这无疑会加重总线的负载。
  另外,总线嗅探只是保证了某个CPU核心的Cache更新数据这个事件能被其他CPU核心知道,但是并不能保证事务串行化。
  于是,有一个协议基于总线嗅探机制实现了事务串行化,也用状态机机制降低了总线带宽压力,这个协议就是MESI协议,这个协议就做到了CPU缓存一致性。
  MESI协议
  MESI协议其实是4个状态单词的开头字母缩写,分别是:Modified,已修改Exclusive,独占Shared,共享Invalidated,已失效
  这四个状态来标记CacheLine四个不同的状态。
  已修改状态就是我们前面提到的脏标记,代表该CacheBlock上的数据已经被更新过,但是还没有写到内存里。而已失效状态,表示的是这个CacheBlock里的数据已经失效了,不可以读取该状态的数据。
  独占和共享状态都代表CacheBlock里的数据是干净的,也就是说,这个时候CacheBlock里的数据和内存里面的数据是一致性的。
  独占和共享的差别在于,独占状态的时候,数据只存储在一个CPU核心的Cache里,而其他CPU核心的Cache没有该数据。这个时候,如果要向独占的Cache写数据,就可以直接自由地写入,而不需要通知其他CPU核心,因为只有你这有这个数据,就不存在缓存一致性的问题了,于是就可以随便操作该数据。
  另外,在独占状态下的数据,如果有其他核心从内存读取了相同的数据到各自的Cache,那么这个时候,独占状态下的数据就会变成共享状态。
  那么,共享状态代表着相同的数据在多个CPU核心的Cache里都有,所以当我们要更新Cache里面的数据的时候,不能直接修改,而是要先向所有的其他CPU核心广播一个请求,要求先把其他核心的Cache中对应的CacheLine标记为无效状态,然后再更新当前Cache里面的数据。
  我们举个具体的例子来看看这四个状态的转换:当A号CPU核心从内存读取变量i的值,数据被缓存在A号CPU核心自己的Cache里面,此时其他CPU核心的Cache没有缓存该数据,于是标记CacheLine状态为独占,此时其Cache中的数据与内存是一致的;然后B号CPU核心也从内存读取了变量i的值,此时会发送消息给其他CPU核心,由于A号CPU核心已经缓存了该数据,所以会把数据返回给B号CPU核心。在这个时候,A和B核心缓存了相同的数据,CacheLine的状态就会变成共享,并且其Cache中的数据与内存也是一致的;当A号CPU核心要修改Cache中i变量的值,发现数据对应的CacheLine的状态是共享状态,则要向所有的其他CPU核心广播一个请求,要求先把其他核心的Cache中对应的CacheLine标记为无效状态,然后A号CPU核心才更新Cache里面的数据,同时标记CacheLine为已修改状态,此时Cache中的数据就与内存不一致了。如果A号CPU核心继续修改Cache中i变量的值,由于此时的CacheLine是已修改状态,因此不需要给其他CPU核心发送消息,直接更新数据即可。如果A号CPU核心的Cache里的i变量对应的CacheLine要被替换,发现CacheLine状态是已修改状态,就会在替换前先把数据同步到内存。
  所以,可以发现当CacheLine状态是已修改或者独占状态时,修改更新其数据不需要发送广播给其他CPU核心,这在一定程度上减少了总线带宽压力。
  事实上,整个MESI的状态可以用一个有限状态机来表示它的状态流转。还有一点,对于不同状态触发的事件操作,可能是来自本地CPU核心发出的广播事件,也可以是来自其他CPU核心通过总线发出的广播事件。下图即是MESI协议的状态图:
  MESI协议的四种状态之间的流转过程,我汇总成了下面的表格,你可以更详细的看到每个状态转换的原因:
  总结
  CPU在读写数据的时候,都是在CPUCache读写数据的,原因是Cache离CPU很近,读写性能相比内存高出很多。对于Cache里没有缓存CPU所需要读取的数据的这种情况,CPU则会从内存读取数据,并将数据缓存到Cache里面,最后CPU再从Cache读取数据。
  而对于数据的写入,CPU都会先写入到Cache里面,然后再在找个合适的时机写入到内存,那就有写直达和写回这两种策略来保证Cache与内存的数据一致性:写直达,只要有数据写入,都会直接把数据写入到内存里面,这种方式简单直观,但是性能就会受限于内存的访问速度;写回,对于已经缓存在Cache的数据的写入,只需要更新其数据就可以,不用写入到内存,只有在需要把缓存里面的脏数据交换出去的时候,才把数据同步到内存里,这种方式在缓存命中率高的情况,性能会更好;
  当今CPU都是多核的,每个核心都有各自独立的L1L2Cache,只有L3Cache是多个核心之间共享的。所以,我们要确保多核缓存是一致性的,否则会出现错误的结果。
  要想实现缓存一致性,关键是要满足2点:第一点是写传播,也就是当某个CPU核心发生写入操作时,需要把该事件广播通知给其他核心;第二点是事物的串行化,这个很重要,只有保证了这个,才能保障我们的数据是真正一致的,我们的程序在各个不同的核心上运行的结果也是一致的;
  基于总线嗅探机制的MESI协议,就满足上面了这两点,因此它是保障缓存一致性的协议。
  MESI协议,是已修改、独占、共享、已失效这四个状态的英文缩写的组合。整个MSI状态的变更,则是根据来自本地CPU核心的请求,或者来自其他CPU核心通过总线传输过来的请求,从而构成一个流动的状态机。另外,对于在已修改或者独占状态的CacheLine,修改更新其数据不需要发送广播给其他CPU核心。

截至目前,盘点2022年搭载120W闪充的手机1小米12SPro全球首发第一代骁龙8处理器,采用台积电4nm制程工艺,性能更强,功耗表现也得到大幅度的改善,体验也跃升新高正面是一块6。73英寸的三星E5发光材料的AMOLED柔Kindle电子书15岁了!在智能手机的洪流中,为何仍有大批拥护者?许多人会记得2007年是iPhone问世的那一年,但在那一年,也诞生了给予全世界爱书人舒适的视觉体验的电子书阅读器Kindle。Kindle除了是亚马逊第一个踏足硬件销售的产品,也光武帝刘秀坐骑在平顶山刨出来的泉就成了湛河源(民间野史)上次说到平顶山市母亲和湛河的历史,咱们今个唠唠湛河的发源地马跑泉的故事。流传故事一坊间相传公元23年,东汉光武帝刘秀,在昆阳把王莽大军打得落花流水,刘秀大军乘胜追击,走之宝丰县境内为了加强集权,在辽代时期的宣徽院,具有哪些特点?辽代宣徽院设置之初仿照后晋而建,实则源自唐代宣徽院的建制规模,随着辽朝中央官制中北南双轨体制的建立,宣徽院在原有机构的基础上做了适当调整,机构和职官规模都有所扩大,宣徽院一分南北是有志者事竟成耿弇他是云台二十八将之一,为东汉的统一立下赫赫战功,主要战绩为平定四十六郡,攻取城池三百余座,同时谦虚低调,深受汉光武帝的信任。耿弇(yn)(3年58年),字伯昭,扶风茂陵(今陕西省兴降龙木文冠果的前世今生一寸木一寸金,降龙木破天门。这是自古以来在民间流传的一句话,讲的正是穆桂英挂帅中穆桂英大破天门阵的传奇故事。故事讲到,杨六郎率军攻打天门阵,被辽军放出毒气所困阻,伤亡惨重,后穆桂英许知远好丑这是我看视频后的第一印象了,你觉得呢但看完后,你会发现这人又很有深度谈到梁启超,提到的是梁启超从出生到认知到老去,梁启超17岁之后才认识到,世界不止有中国,到1929年去世,经历了安史之乱是怎么回事安史之乱发生在唐朝,唐朝是中华历史上继汉朝后的又一个大一统王朝,所谓的汉唐盛世吗。唐朝经历了唐太宗李世民的贞观之治唐高宗李治的永徽之治女皇武则天的治宏贞观政启开元及唐玄宗的开元盛世商鞅变法到底变了什么?背景变法风潮战国时期形势春秋战国时期,是分封制崩溃中央集权制确立的过渡时期。在这一时期,铁制农具的使用和牛耕的逐步推广,导致原有的土地国有制,逐步被土地私有制所代替,地主和农民两大五龙山传奇之二五龙山的来历作者王奎郎五龙山的来历很久很久以前,在龙山地区以东,就是现在的前洼后洼东洼一带,是一片烟波浩淼的湖水。这片湖水南北长约五六里,东西宽约四五里,整个湖呈一个不规则的椭圆形。湖面平静如不忘血染的一二九其实惭愧,最初,我对一二九的了解并不多,但是当我真正去认识一二九,我才发现,这是一群年轻人波澜壮阔的抗日爱国史诗。值此一二九八十七年之际,还有谁在铭记一二九呢?八十七年前的中国,风
便秘是老年高血压患者发生脑卒中的大敌健康人每天规律排出成形软粪一次或每三天一次无不适感,是正常现象。老年高血压便秘者,厕所心脑卒中事件时有发生。这不得不引起人们的警惕!为什么老年高血压患者常容易发生厕所心脑卒中事件呢有一类食物,经常吃不仅会升高血糖,还会升高血压,你要注意了在生活中常吃的食物中,有一类食物既能升高血糖,也会升高血压,你猜到了吗?没错!它就是我们厨房餐桌经常出现的调味品食盐。食盐真的这么可怕吗?多个研究发现中国人食盐摄入量偏高!在英国一中国氢燃料电池行业真正的龙头六大氢燃料电池企业,机构青睐氢燃料电池行业的现状在全球气候变暖等各种压迫之下,对于氢燃料电池这种绿色高效的产品,企业和相关部门格外重视它的开发力度,对于生产企业,在政策和资金上面都有所倾斜,氢燃料电池的高效能葛洲坝水泥争当行业高质量发展引领者中国葛洲坝集团水泥有限公司是国务院国资委所属大型上市国有企业中国能源建设集团有限公司的成员企业,前身为始建于1971年配套葛洲坝水利枢纽工程而兴建的葛洲坝水泥厂。成立50余年来,公uplay育碧进不去一直转圈商店打不开解决办法最近很多玩家反应在登录Uplay育碧客户端的时候遇到了uplay育碧进不去一直转圈商店打不开等问题,很多小伙伴不知道应该如何快速解决,接下来就为大家带来解决的方法。一优化网络环境,陈保平黄岩有朵云世界上有些地方很小,却以物产闻名天下。台州黄岩算是一例。去过黄岩的人不多,但不知道黄岩蜜橘的人一定很少。据史书记载,公元3世纪黄岩就有柑橘,唐朝时还被选为贡品。但黄岩蜜橘让台州以外浙江有座千年古镇,人文景色堪比江南名镇,虽少有人知却值得一游在新安江富春江与兰江三江汇合处,有一座1700多年历史的古城,曾经的这里赫赫有名,堪比杭州如今的这里虽然成了一座镇子,知名度也没有往昔那般大了,却也不失为一处世外桃源般的存在。这里雨中登梵净山题记人生路待我了无牵挂,漂泊四海为家野游西北之北,徜徉大漠黄沙阿里山巅对歌,黄浦江边溜达西子湖畔浣纱,饮酒苗寨醉榻蒙古草原跳舞,八达岭上攀爬就此峰回路转,去观洱海三塔走过青石街衢,10元人民币背后的风景,就在重庆市的这个县,刚通高铁,赶紧来玩这里是刘小顺的旅行和生活研究所。现在随着互联网移动支付越来越发达,大家似乎使用纸质人民币的机会越来越少了,但是人民币背面的设计图案一直都被大家津津乐道,代表了祖国的大好河山。而在11971年,一个老乞丐来找杨得志我是你的兵,请帮我证明身份1971年,一个老乞丐来找杨得志我是你的兵,请帮我证明身份!1971年的一天,济南军区大门前来了一位衣衫褴褛的老者,天气已经是暮春时节,但老人却穿着一身厚厚的棉衣,棉衣又脏又破,手成吉思汗墓之谜目击者声称,7层银棺被牢牢锁住我国是一个有着悠久历史的国家,五千年的文化沉淀也让我国境内留下了大量的瑰宝,其中就有着一位千古大帝,那就是被毛主席誉为一代天骄的元太祖成吉思汗。他的一生可谓传奇,在他率领之下的蒙古
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网