4.6 Cache Write Policy
如果有可能,我愿意放弃使用Write操作,Write操作不是在进行单纯地进行写,而是将Read建立的千辛万苦异常小心地毁于一旦,是Cache Hierarchy设计苦难的发源地。没有写操作在Cache Block中就不会有这么多状态,更没有复杂的Memory Consistency模型。
很多人都不喜欢写操作,这并不能阻挡它的真实存在。绝大多数人痛恨写操作,也不愿意去研究如何提高写操作的效率,写虽然非常讨厌,但是很少在速度上拖累大家,只是写太快了,带来了许多副作用经常影响大家。不允许写操作使用Cache貌似是个方法,却几乎没有程序员能够做到这一点。过分的限制写操作也并非良策,凡事总有适度。
这使得在CacheHierarchy设计中读写操作得到了区别对待。读的资质差了一些,有很多问题亟待解决,最Critical的是如何提高Load-Use Latency;对于写,只要不给大家添乱就已经足够,Cache Bus的Bandwidth能少用点就少用点,能降低一点Bus Traffic就算一点,实在不能少用,就趁着别人不用的时候再用。从总线带宽的角度上看,Load比Store重要一些,在进行Cache优化时,更多的人关心读的效率。
在一个程序的执行过程中不可能不使用Write操作。如何在保证Memory Consistency的前提下,有效降低Write操作对Performance的影响,如何减少Write Traffic,是设计的重中之重。在一个处理器系统中,Write操作需要分两种情况分别讨论,一个是Write Hit,另一个是Write Miss。Write Hit指在一次Write操作在进行Probe的过程中在当前CMP的Cache Hierarchy中命中,而Write Miss指没有命中。
我们首先讨论WriteHit,从直觉上看Write Hit相对较为容易,与此相关的有些概念几乎是常识。Write Hit时常用的处理方法有两种,一个是Write Through,另一个是Write Back[1]。相信绝大部分读者都明白这两种方法。Write Through方法指进行写操作时,数据同时进入当前Cache,和其下的一级Cache或者是主存储器;Write Back方法指进行写操作时,数据将直接写入当前Cache,而不会继续传递,当发生Cache Block Replace时,被改写的数据才会更新到其下的Cache或者主存储器中。
很多人认为Write-Back在降低Write Traffic上优于Write-Though策略,只是Write-Back的实现难于Write-Though,所以有些低端处理器使用了Write-Though策略,多数高端处理器采用Write-Back策略。
这种说法可能并不完全正确,也必将引发无尽的讨论。在没有拿到一个微架构的全部设计,在没有对这个微架构进行系统研究与分析之前,并不能得出其应该选用Write-Through或者是Write-Back策略的结论。即便拿到了所有资料,进行了较为系统的Qualitative Research和Quantitative Analysis之后,你也很难得出有说服力的结论。
在目前已知的高端处理器中,SUN的Niagara和Niagara 2微架构的L1 Cache使用Write-Through策略[81],AMD最新的Bulldozer微架构也在L1 Cache中使用Write-Through策略[74]。Intel的Nehalem和Sandy Bridge微架构使用Write-Back策略。Write-Through和Write-Back策略各有其优点和不足,孰优孰劣很难说清。
Norman P.Jouppi列举了Write-Through策略的3大优点,一是有利于提高CPU Core至L1 Cache的总线带宽;二是Store操作可以集成在指令流水线中;三是Error-Tolerance [97]。这篇文章发表与1993年,但是绝大部分知识依然是Cache Write Policies的基础,值得借鉴。
其中前两条优点针对DirectMapped方式,非本节的重点,读者可参考[97]获得细节。制约Cache容量进一步增大的原因除了成本之外,还有Hit Time。如上文已经讨论过的,随着Cache容量的增加,Hit Time也随之增大。而Cache很难做到相对较大,这使得选择Direct Mapped方式时需要挑战John和David的2:1 Cache Rule of Thumb,目前在多处处理器系统中都不在使用Direct Mapped方式。
对这些Rule ofThumb的挑战都非一蹴而就。在某方面技术取得变革时,首先要Challenge的恰是之前的Rule of Thumb。善战者择时而动,而善战者只能攻城掠地,建立一个与旧世界类同的新世界,不会带来真正的改变。
革新者远在星辰之外,经得住大悲大喜,大耻大辱,忍受得住Stay Hungry Stay Foolish所带来的孤单寂寞。是几千年前孟子说过的“富贵不能淫,贫贱不能移,威武不能屈。居天下之广居,立天下之正位,行天下之大道。得志,与民由之,不得志,独行其道”。几千年祖辈的箴言真正习得是西方世界。
忽略以上这段文字。我们继续讨论Norman P.Jouppi提及的使用Write-Through策略的第三个优点,Error-Tolerance。CMOS工艺在不断接近着物理极限,进一步缩短了门级延时,也增加了晶体管的集成度,使得原本偶尔出现的Hard Failures和Soft Errors变得更加濒繁。这一切影响了SRAM Cells的稳定性,导致在基于SRAM Cells的Cache Memory中,Hard和Soft Defects不容忽视。
采用Write-Back策略的Cache很难继续忍受Single Bit的Defects,被迫加入复杂的ECC校验;使用Write-Though策略,Cache因为仍有数据副本的存在只需加入Parity Bit。与ECC相比,Parity Bit所带来的Overhead较小。这不是采用ECC校验的全部问题,在一个设计中,为了减少Overhead,需要至少每32位或者更多位的参与产生一次ECC结果。这些Overhead的减少不利于实现Byte,Word的Store操作,因为在进行这些操作时,需要首先需要读取32位数据和ECC校验,之后再Merge and Write新的数据并写入新的ECC校验值。
除此之外使用Write-Though策略可以极大降低Cache Coherence的实现难度,没有Dirty位使得多数设计更为流畅。但是你很难设想在一个ccNUMA处理器系统中,Cache的所有层次结构都使用Write-Though策略。由此带来的各类Bus Traffic将何等壮观。
采用Write-Though策略最大的缺点是给其他Cache层次带来的Write Traffic,而这恰恰是在一个Cache Hierarchy设计过程中,要努力避免的。为了降低这些Write Traffic,几乎所有采用Write-Though策略的高端处理器都使用了WCC(Write Coalescing Cache)或者其他类型的Store-Though Queue,本节仅关注WCC。
假设一个微架构的L1Cache采用Write-Through方式。WCC的作用是缓冲或者Coalescing来自L1 Cache的Store操作,以减少对L2 Cache的Write Traffic。在使用WCC时,来自L1 Cache的Store操作将首先检查WCC中是否含有与其地址相同的Entry,如果有则将数据与此Entry中的数据进行Coalescing;如果没有Store结果将存入WCC的空闲Entry中;如果WCC中没有空闲Entry则进行Write Through操作。WCC的大小决定了Write Traffic减少的程度。WCC的引入也带来了一系列Memory Consistency问题。
采用Write-Back策略增加了Cache Coherency设计难度,也有效降低了Write Traffic,避免了一系列Write-Through所带来的问题。下文以GEM5中的MOESI_CMP_directory为例简要Write-Back策略的实现方法。
如果WriteHit的Cache Block处于Exclusive[2]状态时,数据可以直接写入,并通知CPU Core Write操作完成。Write Hit的Cache Block处于Shared或者Owner状态时的处理较为复杂。即便是采用Write-Through策略,这种情况的处理依然较为复杂,只是Cache间的状态转换依然简单很多。本节仅介绍命中了Shared状态这种情况。
在L1Cache层面,这个Write Hit命中的Cache Block,其状态将会从S状态迁移到MM_W状态,之后经过一段延时迁移到MM状态。在MOESI_CMP_directory Protocol中,如果L2 Cache Block的状态为ILS,ILO,ILOS,SLS,OLS和OLSX时,L1 Cache中必定含有对应的状态为S的Block。由于Accidentally Inclusive的原因,L1 Cache Block多数时候在L2 Cache中具有副本,因此必须要考虑L1 Cache Block进行状态迁移时对L2 Cache Controller的影响。不仅如此还需要考虑CMP间Cache Coherency使用的Directory。
我们首先考虑L1 CacheBlock的从S开始的状态迁移过程。当CPU Core的Cache Hit到某个状态位S的L1 Cache Block后便开始了一次长途旅行。在这个Clock Block的S状态将经由SM,OM,最终到达MM_W和MM状态,如图4‑15所示。
CPU Core进行Store操作,Cache Hit一个状态为S的Block时,首先迁移到SM状态,之后在收到Data或者Exclusive Data之后进入到OM状态,OM状态到MM_W状态的迁移过程与图4‑14的过程类似。本节重点关注b_issueGETX请求,这个请求被称为Read for Exclusive。
在一个ccNUMA处理器系统中,b_issueGETX请求虽然复杂依然有机可循,首先在Intra-CMP中尝试并获得对访问Cache Block的Exclusive权限。如果没有获得Exclusive权限,则将这个请求转发给Directory Controller,并由Home Agent/Node经由CMP间的互联网络发送给其他CMP直到获得Exclusive权限。
在MOESI_CMP_directoryProtocol中,Cache Block的状态为S表示在当前ccNUMA处理器系统中至少还存在一个数据副本,因此b_issueGETX请求将首先在Intra-CMP中进行,并通过requestIntraChipL1Network_out发送至L2 Cache Controller。
L2 CacheController通过L1requestNetwork_in获得b_issueGETX请求,如果在L2 Cache中包含访问的数据副本,b_issueGETX请求将转换为L1_GETX请求。在L2 Cache中包含L1 Cache Block为S状态数据副本的情况有很多,还有一些L2 Cache Block包含数据副本,但是在当前CMP中其他L1 Cache中也包含数据副本的情况。这些状态转移的复杂程度如果我能够用语言简单描述,就不会有SLICC这种专用语言的存在价值。
如果在Intra-CMP中可以处理b_issueGETX请求,并不算太复杂,如果不能,而且L2 Cache Block的状态为SLS时,需要进一步做Inter-CMP Coherence的处理,此时b_issueGETX请求将转换为a_issueGETX,并通过globalRequestNetwork_out继续发送至Directory Controller。此时Directory Controller通过requestQueue_in获得该请求,并将其转换为GETX请求。Directory中具有4个Stable状态M,O,S和I,不同的状态对于GETX请求的处理不尽相同。
如果处于O状态,此时Intra-CMP为该Cache Block的Owner,此时仅需要向其他Inter-CMP发送g_sendInvalidations请求,并可将Exclusive_Data转发至上层,L1 Cache Block的状态也因此迁移为OM。
如果在Directory中没有记录哪些CMP中具有状态为S的数据拷贝时,g_sendInvalidations请求将广播到所有参与Cache Coherence的CMP处理器中,这种方式带来的Bus Traffic非常严重,也是这个原因在Directory中多设置了Bit Vectors,用来记录哪些CMP中具有状态为S的数据副本。
在这种情况下g_sendInvalidations请求仅需发送到指定的CMP,而不需要进行广播。因为Memory Consistence的原因,发起请求的CMP必须要等待这些指定的CMP返回所有的ACK后,才能进一步完成CPU Core的Store操作。除了在Directory中设置了Bit Vectors之外,Intel的MESIF中的F状态也可以在某种程度上避免因为过多的ACK带来的Bus Traffic。
通常情况在CMP间的连接拓扑不会使用Share Bus方式,对于Request/ACK这种数据请求模式,采用Share Bus方式最大的好处是具有一个天然的全局同步点,这个同步点在严重影响了总线带宽的前提下,极大了降低了设计难度。
采用ShareBus方式时,随着总线上节点数目的增加,冲突的概率也以O(N!)级别的算法复杂度进一步增长。这使得一个可用的CMP间的互联方式极少采用Share-Bus方式。采用其他方式,无论是Ring-Bus或者更加复杂的拓扑结构,都会涉及到多个数据通路,这使得从这些CMP返回的ACK并没有什么顺序,Home Agent/Node不能接收到一个ACK就向上转发一次,而是收集后统一转发。
当L1 CacheBlock收到All_acks后,将从OM状态转移为MM_W状态,完成最后的操作,其过程与图4‑14所示相同。为简略起见,本节不再介绍在Directory中是M,S和I状态的情况。而专注与Write Miss的处理。
Norman P.Jouppi从两个方面讨论Write Miss的处理策略。首先是否为每一个Miss的请求重新准备一个Cache Block,因此产生了两种方法,Write-Allocate或者No-Write Allocate。如果使用Write-Allocate方法,Cache Controller为Miss请求在当前Cache中分配一个新的Cache Block,否则不进行分配;
其次是否需要从底层Cache中获取数据,因此产生了两种处理方法,Fetch-on-Write或者No-Fetch-on-Write方法,如果采用Fetch-on-Write方法,Cache Controller将从其下Cache层次结构中Fetch已经写入的数据,并进行Merge操作后统一的进行写操作,否则不进行Fetch。还有一种方法是Write-Before-Hit,这种实现方法多出现在Direct Mapped Write Through Cache中,本节对此不再关注。
Write-Allocate与Fetch-on-Write方法没有必然联系,但是这两种方法经常被混淆,以至于后来没有更正的必要与余地,通常意义上微架构提到的Write-Allocate策略是Write-Allocate与Fetch-on-Write的组合;实际上Write-Allocate也可以与No-Fetch-on-Write混合使用,该方法也被称为Write-Validate,这种方法很少使用;No-Write Allocate与No-Fetch-on-Write的组合被称为Write-Around,如表4-5所示。
表4-5 Write-Allocate与Fetch-on-Write的组合[3]
Fetch-on-Write |
No-Fetch-on-Write |
|
Write-Allocate |
Write-Allocate |
Write-Validate |
No-Write Allocate |
N.A. |
Write-Around |
我们假设一个处理器系统的MemoryHierarchy包含L1,L2 Cache和主存储器,而Cache Miss发生在L1 Cache。并在这种场景下,分析Write-Allocate,Write-Validate和Write-Around这三种方法的实现。
当Write L1 CacheMiss而且使用Write-Allocate方法时,L1 Cache Controller将分配一个新的Cache Block,之后与Fetch的数据进行合并,然后写入到L1 Cache Block中。这种方法较为通用,但是带来了比较大的Bus Traffic。
新分配一个CacheBlock往往意味着Replace一个旧的Cache Block,如果这个Cache Block中含有Dirty数据,Cache Controller并不能将其Silent Eviction,而是需要进行Write-Back;其次Fetch操作本身也会带来不小的Bus Traffic。
Write-Around策略是No-Write Allocate和No-Fetch-on-Write的策略组合。使用这种方法时,数据将写入到L2 Cache或者主存储器,并不会Touch L1 Cache。当Cache Miss时,这种方法并不会影响Memory Consistency。但是这种方法在Cache Hit时,通常也会Around到下一级缓冲,这将对Memory Consistency带来深远的影响。
虽然我能构造出很多策略解决这些问题,但是这些方法都不容易实现。读者可以很自然的想到一种方法,就是在Cache Hit时不进行这个Around操作,对此有兴趣的读者可以进一步构想在这种情况之下,如何在保证Memory Consistency的情况较为完善的处理Cache Hit和Miss两种情况。本节对此不再进一步说明。
Write-Validate策略是No-Fetch-on-Write和Write-Allocate的策略组合。使用这种方法时,L1 Cache Controller首先将将分配一个新的Cache Block,但是并不会向Fetch其下的Memory Hierarchy中的数据。来自CPU Core的数据将直接写入新分配的L1 Cache Block中,使用这种方法带来的Bus Traffic非常小。
但是来自CPUCore的数据不会是Cache Block对界操作,可能是Byte,Word或者是DWord,L1 Cache必须要根据访问粒度设置使能位,这个使能位可以是By Byte,Word或者是Dword,也因此带来的较大的Overhead。当进行Cache Write操作时,除了要写入的数据的使能位置为有效外,其他所有位都将置为无效。在使用这种方法时,有效数据可能分别存在与L1 Cache和L2 Cache,这为Memory Consistence的实现带来了不小的困难。
No-WriteAllocate和Fetch-on-Write的策略组合没有实际用途。从其下Memory Hierarchy Fetch而来的数据因为没有存放位置,在与CPU Core的数据进行合并后,依然需要发送到其下的Memory Hierarchy。几乎没有什么设计会进行这种不必要的两次总线操作。
在WriteMiss的处理方法中,Write-Allocate和Write-Around策略较为常用,Write-Validate策略并不常用。Write Miss的处理方法与Write Hit存在一定的依赖关系。Write-Around需要与Write-Through策略混合使用,而Write-Allocate适用于Write-Through和Write-Back策略。
在一个ccNUMA处理器系统中,与Write操作相关的处理更为复杂。本节介绍的Hit Miss实现策略各有其优点,所有这些策略所重点考虑的依然是如何降低因为Write而带来的Bus Traffic和Memory Consistency。
[1] 还有一种是上文提及的WriteOnce,Write Once是Write Through和Write Back的联合实现。
[2] M,M_W,MM和MM_W状态都属于Exclusive状态。
[3] 表4-5源自[74],并有所改动。
4.6 Cache Write Policy相关推荐
- Cache Memory技术示例
Cache Memory技术示例 为什么需要cache?如何判断一个数据在cache中是否命中?cache的种类有哪些,区别是什么? 为什么需要cache memory 先思考第一个问题:程序是如何运 ...
- [mmu/cache]-ARM cache的学习笔记-一篇就够了
★★★ 个人博客导读首页-点击此处 ★★★ . 说明: 在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 64位 . 相关文章 1.ARM MMU的学习笔记-一篇就 ...
- T级图片数据Cache思路以及图片服务器搭建方法
通过 pp.sohu.com,淘宝,拍拍网的域名分析: 1871.img.pp.sohu.com.cn ,1872.img.pp.sohu.com.cn,1873.img.pp.sohu.com.cn ...
- 浅入浅出Caffeine cache
背景 公司项目中有用到caffeine cache 所以来了解一下. 本地缓存也就是我们适用内存缓存一些热点数据,使应用程序的程序处理的更加的快.以及保护我们的一些有磁盘/网络IO操作的函数/方法,以 ...
- 《浅谈Cache Memory》 学习-第四章
Cache的层次结构 我第一次接触存储器瓶颈这个话题是在上世纪九十年代,距今已接近二十年.至今这个问题非但没有缓和的趋势,却愈演愈烈,进一步发展为Memory Wall.在这些问题没有得到解决之前,片 ...
- 浅谈Cache Memory--目录
序 第1章有关Cache的思考 1.1 Cache不可不察也 1.2 伟大的变革 1.3 让指令飞 1.4 Crime and Punishment 第2章Cache的基础知识 2.1 Cache的工 ...
- 高速缓冲存储器--Cache
本篇参考 arm 官网公开材料,和微信公众号 老秦谈芯 学习笔记 宋宝华:深入理解cache对写好代码至关重要(上) 深入学习Cache系列 1: 带着几个疑问,从Cache的应用场景学起 深入学习C ...
- Cache的基本原理
对于没有接触过底层技术的朋友来说,或许从未听说过cache.毕竟cache的存在对程序员来说是透明的.在接触cache之前,先为你准备段code分析: int arr[10][128];for (i ...
- Cache的基本原理以及简单操作
对于没有接触过底层技术的朋友来说,或许从未听说过cache.毕竟cache的存在对程序员来说是透明的.在接触cache之前,先为你准备段code分析. int arr[10][128];for (i ...
最新文章
- Java项目:学生考勤管理系统(java+SSM+Poi导出+Easyui+JFreeChart+maven+mysql)
- 搭建云mysql,基于ECS搭建云上博客
- linux 命令输出 保存到文件 日志记录
- SearchRecentsuggestionsProvider
- h3c s7506e 配置手册_H3C交换机s5500Web登录配置
- Android WebView重定向问题,Android WebView 重定向问题
- Java新手造假_老板居然让我在Java项目中“造假”
- 详解自然语言处理5大语义分析技术及14类应用(建议收藏)
- 世界500强牛企英语面试精彩问答
- 网络:Server returned HTTP response code: 400(url中文)
- Git学习总结(14)——Git使用前的注意事项
- 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(1月9日-1月15日)
- 存储过程循环遍历一个月的每一天的函数_3.3 循环
- Linux SSHD服务安装与维护详解(一)——SSHD安装、启动与密钥认证实现
- javaweb项目设计文档
- R语言安装教程 | 图文介绍超详细
- Eclipse下载版本的选择
- 计算机电源改造加大功率,最标准的电脑电源功率计算公式 十代酷睿电源搭配建议...
- android 快速开发(二)辅助类的使用,kotlin枚举类反射
- 舒老师的hu测(日常吐槽)
热门文章
- 【P02】OP并联缓冲器
- 【前端性能优化】浏览器渲染原理与性能优化
- matlab利用conv函数验证卷积和的交换律_分配律和结合律,【判断题】卷积运算满足三个基本代数运算规律:交换律、结合律和分配律。...
- 东师计算机应用基础20在线作业3,东师计算机应用基础-18春在线作业3-1.docx
- 自动泊车之停车位检测算法
- 如何识别人的技术能力和水平?
- oracle的mins,分钟的缩写是min还是mins?
- SpringBoot Endpoint
- 想要减少广告浪费,你需要学会这些设计常识
- 流式大数据实时处理技术、平台及应用