A. CPU多级缓存架构
1、基本概念
1.1、总线
前端总线(FSB)就是负责将CPU连接到内存的一座桥,前端总线频率则直接影响CPU与内存数据交换速度,如果FSB频率越高,说明这座桥越宽,可以同时通过的车辆越多,这样CPU处理的速度就更快。目前PC机上CPU前端总线频率有533MHz、800MHz、1066MHz、1333MHz、1600MHz等几种,前端总线频率越高,CPU与内存之间的数据传输量越大。
前端总线——Front Side Bus(FSB),是将CPU连接到北桥芯片的总线。选购主板和CPU时,要注意两者搭配问题,一般来说,前端总线是由CPU决定的,如果主板不支持CPU所需要的前端总线,系统就无法工作。
1.2、频率与降频
只支持1333内存频率的cpu和主板配1600内存条就会降频。核心数跟ddr2和ddr3没关系,核心数是cpu本身的性质,cpu是四核的就是四核的,是双核的就是双核的。如果cpu只支持1333,而主板支持1600,那也会降频;cpu支持1600而主板只支持1333那不仅内存会降频,而且发挥不出cpu全部性能。
另外如果是较新的主板cpu,已经采用新的qpi总线,而不是以前的fsb总线。以前的fsb总线一般是总线为多少就支持多高的内存频率。而qpi总线的cpu集成了内存控制器,5.0gt/s的cpu可能只支持1333内存频率,但是总线带宽相当于1333内存的内存带宽的两倍,这时候,组成1333双通道,内存速度就会翻倍,相当于2666的内存频率。
1.3、cache line
Cache Line可以简单的理解为CPU Cache中的最小缓存单位。目前主流的CPU Cache的Cache Line大小都是64Bytes。假设我们有一个512字节的一级缓存,那么按照64B的缓存单位大小来算,这个一级缓存所能存放的缓存个数就是512/64 = 8个。
2、CPU多级缓存架构
级别越小的缓存,越接近CPU, 意味着速度越快且容量越少。
3、多核CPU多级缓存一致性协议MESI
为了解决这个问题,芯片设计者制定了一个规则。当一个 CPU 修改高速缓存行中的字节时,计算机中的其它 CPU 会被通知,它们的高速缓存将视为无效。于是,在上面的情况下, CPU2 发现自己的高速缓存中数据已无效, CPU1 将立即把自己的数据写回 RAM ,然后 CPU2 重新读取该数据。 可以看出,高速缓存行在多处理器上会导致一些不利。
多核CPU的情况下有多个一级缓存,如何保证缓存内部数据的一致,不让系统数据混乱。这里就引出了一个一致性的协议MESI。
MESI 是指4中状态的首字母。每个Cache line有4个状态,可用2个bit表示,它们分别是:
注意: 对于M和E状态而言总是精确的,他们在和该缓存行的真正状态是一致的,而S状态可能是非一致的。如果一个缓存将处于S状态的缓存行作废了,而另一个缓存实际上可能已经独享了该缓存行,但是该缓存却不会将该缓存行升迁为E状态,这是因为其它缓存不会广播他们作废掉该缓存行的通知,同样由于缓存并没有保存该缓存行的的数量,因此(即使有这种通知)也没有办法确定自己是否已经独享了该缓存行。
从上面的意义看来E状态是一种投机性的优化:如果一个CPU想修改一个处于S状态的缓存行,总线事务需要将所有该缓存行的变成invalid状态,而修改E状态的缓存不需要使用总线事务。
3.2、MESI状态转换
1.触发事件
触发事件描述本地读取(Local read)本地cache读取本地cache数据本地写入(Local write)本地cache写入本地cache数据远端读取(Remote read)其他cache读取本地cache数据远端写入(Remote write)其他cache写入本地cache数据
2.cache分类:
前提:所有的cache共同缓存了主内存中的某一条数据。
本地cache:指当前cpu的cache。
触发cache:触发读写事件的cache。
其他cache:指既除了以上两种之外的cache。
注意:本地的事件触发 本地cache和触发cache为相同。
下图示意了,当一个cache line的调整的状态的时候,另外一个cache line 需要调整的状态。
3.3、多核缓存协同操作
假设有三个CPU A、B、C,对应三个缓存分别是cache a、b、 c。在主内存中定义了x的引用值为0。
单核读取
那么执行流程是:
CPU A发出了一条指令,从主内存中读取x。
从主内存通过bus读取到缓存中(远端读取Remote read),这是该Cache line修改为E状态(独享).
双核读取
那么执行流程是:
CPU A发出了一条指令,从主内存中读取x。
CPU A从主内存通过bus读取到 cache a中并将该cache line 设置为E状态。
CPU B发出了一条指令,从主内存中读取x。
CPU B试图从主内存中读取x时,CPU A检测到了地址冲突。这时CPU A对相关数据做出响应。此时x 存储于cache a和cache b中,x在chche a和cache b中都被设置为S状态(共享)。
修改数据
那么执行流程是:
CPU A 计算完成后发指令需要修改x.
CPU A 将x设置为M状态(修改)并通知缓存了x的CPU B, CPU B将本地cache b中的x设置为I状态(无效)
CPU A 对x进行赋值。
同步数据
那么执行流程是:
CPU B 发出了要读取x的指令。
CPU B 通知CPU A,CPU A将修改后的数据同步到主内存时cache a 修改为E(独享)
CPU A同步CPU B的x,将cache a和同步后cache b中的x设置为S状态(共享)。
MESI优化和他们引入的问题
缓存的一致性消息传递是要时间的,这就使其切换时会产生延迟。当一个缓存被切换状态时其他缓存收到消息完成各自的切换并且发出回应消息这么一长串的时间中CPU都会等待所有缓存响应完成。可能出现的阻塞都会导致各种各样的性能问题和稳定性问题。
CPU切换状态阻塞解决-存储缓存(Store Bufferes)
比如你需要修改本地缓存中的一条信息,那么你必须将I(无效)状态通知到其他拥有该缓存数据的CPU缓存中,并且等待确认。等待确认的过程会阻塞处理器,这会降低处理器的性能。应为这个等待远远比一个指令的执行时间长的多。
Store Bufferes
为了避免这种CPU运算能力的浪费,Store Bufferes被引入使用。处理器把它想要写入到主存的值写到缓存,然后继续去处理其他事情。当所有失效确认(Invalidate Acknowledge)都接收到时,数据才会最终被提交。 这么做有两个风险
Store Bufferes的风险 第一、就是处理器会尝试从存储缓存(Store buffer)中读取值,但它还没有进行提交。这个的解决方案称为Store Forwarding,它使得加载的时候,如果存储缓存中存在,则进行返回。 第二、保存什么时候会完成,这个并没有任何保证。
试想一下开始执行时,CPU A保存着finished在E(独享)状态,而value并没有保存在它的缓存中。(例如,Invalid)。在这种情况下,value会比finished更迟地抛弃存储缓存。完全有可能CPU B读取finished的值为true,而value的值不等于10。
即isFinsh的赋值在value赋值之前。
这种在可识别的行为中发生的变化称为重排序(reordings)。注意,这不意味着你的指令的位置被恶意(或者好意)地更改。
它只是意味着其他的CPU会读到跟程序中写入的顺序不一样的结果。
3.4、硬件内存模型
执行失效也不是一个简单的操作,它需要处理器去处理。另外,存储缓存(Store Buffers)并不是无穷大的,所以处理器有时需要等待失效确认的返回。这两个操作都会使得性能大幅降低。为了应付这种情况,引入了失效队列。它们的约定如下:
原文连接
B. volitate 原理
volatile保证多线程可见性,volatile修饰的变量不会引起上下文切换和调度
cpu缓存,cpu运算速度与内存读写不匹配,因为cpu运算速度比内存读写快的多
从主内存中获取或者写入数据会花费很长时间,现在大多数cpu都不会直接访问内存,而是访问cpu缓存,cpu缓存是cpu与主内存之间的临时存储器,容量小,交换速度快,缓存中的数据是内存中的一小部分数据,是cpu即将访问的。当cpu调用大量数据时候,就先从缓存中读取从而加快读取速度
按照读取顺序与cpu结合的紧密程度,cpu缓存分为
一级缓存:L1位于cpu内核旁边,是与cpu结合最为紧密的cpu缓存
二级缓存:L2分为内部和外部两种芯片,内部芯片二级缓存运行速度与主频相同,外部芯片二级缓存运行速度则只有主频的一半
三级缓存,只有高端的cpu才有
每一级缓存中所存储的数据都是下一级缓存中存储的数据的一部分
cpu要读取一个数据的时候,首先从一级缓存中查找,如果没有就从二级中查找,如果还没有就从三级缓存中或者是内存总进行查找,一般来说,每级缓存的命中率大概有0.8左右,也就是全部数据量的0.8可以在一级缓存中查到,只有剩下的0.2总数据量从二级缓存中或者是三级缓存或者是内存中读取
缓存行:缓存是分line的,一个段对应一个缓存行,是cpu缓存种可分配的最小存储单元,通常是64字节:当cpu看到一条读取内存的指令的时候,会把内存地址传递给一级缓存,一级缓存会检查它是否有这个内存地址对应的缓存段,如果没有就把整个缓存段从内存共或者更高级的缓存种加载进来。
cpu执行计算的过程为:程序和数据被加载到主内存中,指令和数据被加载到cpu缓存中,cpu执行指令将结果写入cpu缓存中,cpu缓存中的数据写回到主内存中,但是这种方式仅限于单核cpu的时候
如果服务器是多核cpu呢,
多核处理器中主内存核处理器一样是分开的,这时候,L3作为统一的高速缓存共享,处理器1拥有自己的L1 L2
这个时候当核0读取了一个字节根据局部性原理,与他相邻的字节同样会被读入核0的缓存中
核3也读取了同样的一个字节,根据局部性原理,与他相邻的字节同样会被读入到核3的数据中
此时,核0和核3的缓存中拥有同样的数据
核0修改了那个字节之后,被修改后那个字节被回写到了核0的缓存中,但是该信息并没有回写到主内存
当核3访问该数据的时候,造成该数据不同步
为了解决这个问题**,当一个cpu修改缓存中的字节的时候,**服务器中其他cpu的会被通知他们的缓存将是为无效,这样核1在修改缓存中的数据的时候,核3会发现自己的缓存中的数据已经无效,核0将自己的写回到主内存中,然后核3将重新读取该数据
将代码转化为汇编指令的时候发现在汇编指令add之前有一个lock指令,lock指令就是关键。
lock指令的作用:在修改内存的时候使用lock前缀指令调用加锁的读修改写操作,保证多处理器系统总处理器之间进行可靠的通讯
1.锁总线,其他cpu对内存的读写请求会被阻塞,直到锁释放,不过实际候来的处理器都采用了缓存缓存代替锁总线,因为总线开销过大,锁总线的时候其他cpu没办法访问内存
2.lock后的写操作会回写已经修改的数据,同时让其他cpu相关缓存行失效,从而重新从内存中加载最新的数据
3.不是内存屏障却能完成内存屏障的功能,阻止屏障两边的指令重排序
嗅探式的缓存一致性协议:所有内存的传输都发生在一条共享的总线上,而所有的处理器都能看到这条总线,缓存本身是独立的,但是内存是共享的。所有的内存访问都要进行仲裁,即同一个指令周期种只有一个cpu缓存可以读写数据。cpu缓存不仅在内存传输的时候与总线打交道,还会不断的在嗅探总线上发生数据交换跟踪其他缓存在做什么,所以当一个cpu缓存代表它所属的处理器读写内存的时候,其他的处理器都会得到通知(主动通知),他们以此使自己的缓存保存同步。只要某个处理器写内存,其他处理器就马上直到这块内存在他们的缓存段种已经失效。。
MESI协议是缓存一致性协议,在MESI协议中每个缓存行有四个状态,Modified修改的,表示这行数据有效,数据被修改了和内存中的数据不一致,数据只存在当前cache中,Exclusive独有的,这行数据有效,数据和内存中的数据一致,数据只存在在本cache中,Shared共享的,这行数据有效,数据和内存中的数据一致,数据存在很多cache中,Invalid这行数据无效,这里的Invalid shared modified都符合我们的嗅探式的缓存一致性协议,但是Exclusive表示独占的,当前数据有效并且和内存中的数据一致,但是只在当前缓存中,Exclusive状态解决了一个cpu缓存在读写内存的之前我们要通知其他处理器这个问题,只有当缓存行处于Exclusive和modified的时候处理器才能写,也就是说只有在这两种状态之下,处理器是独占这个缓存行的,当处理器想写某个缓存行的时候,如果没有独占权就必须先发送一条我要独占权的请求给总线,这个时候会通知处理器把他们拥有同一缓存段的拷贝失效,只要在获得独占权的时候处理器才能修改数据并且此时这个处理器直到这个缓存行只有一份拷贝并且只在它的缓存里,不会有任何冲突,反之如果其他处理器一直想读取这个缓存行(马上就能直到,因为一直在嗅探总线),独占或已修改的缓存行必须要先回到共享状态,如果是已经修改的缓存行,还要先将内容回写到内存中。
volatile变量的读写
工作内存其实就是cpu缓存,当两条线程同时操作主内存中的一个volatile变量时候,A线程写了变量i,此时A线程发出lock指令,发出的lock指令锁总线或者锁缓存行,同时线程b的高速缓存中的缓存行内容失效,线程A想内存中回写最新的i。当线程B读取变量的时候,线程发现对应地址的缓存行被锁了等待锁释放,锁的一致性协议会保证它读取到最新的值。
C. 高速跟踪缓存是什么
、高速缓存的概念和原理
1、高速缓存出现的原因
高速缓存(Cache)的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。为了减少这种情况的发生,人们就想到了使用Cache,它采用一种读写速度要比系统内存快很多的特殊静态内存。系统工作时,将运行时要经常存取的一些数据从系统内存读取到Cache中,而CPU会首先到Cache中去读取或写入数据,如果Cache中没有所需数据(或Cache已满,无法再写入),则再对系统内存进行读写,另外Cache在空闲时也会与内存交换数据。其实质就是是在慢速DRAM和快速CPU之间插入一速度较快、容量较小的SRAM,起到缓冲作用,使CPU既可以以较快速度存取SRAM中的数据,提高系统整体性能,又不使系统成本上升过高。
2、高速缓存的工作原理
Cache的工作原理是基于计算机程序访问的局部性。对大量典型程序运行情况的分析结果表明,在一个较短的时间间隔内,由程序产生的地址往往集中在存储器逻辑地址空间的很小范围内。对这些地址的访问具有时间上集中分布的倾向。数据分布以及工作单元的选择都可以使存储器地址相对集中。这种对局部范围的存储器地址频繁访问,而对此范围以外的地址则访问甚少的现象,就称为程序访问的局部性。根据程序的局部性原理,就为Cache的存在提供了理论依据,系统正是依据此原理,不断地将与当前指令集相关联的一个不太大的后继指令集从内存读到Cache,然后再与CPU高速传送,从而达到速度匹配。
3、高速缓存的分级结构
CPU高速缓存是分级构造的,一般由L1和L2两极构成,通常L1 Cache的速度最快,与CPU核心的距离也最近,但容量较小,而L2 Cache 速度稍慢,但容量较大。Cache采用分级结构的主要理由在于:对于一个典型的一级缓存系统的80%的内存申请都发生在CPU内部,只有20%的内存申请是与外部内存打交道。而这20%的外部内存申请中的80%又与二级缓存打交道。因此,采用分级结构将更加有利于效能的提升和成本的合理分配。
这种分层的高速缓存布局有助于弥合处理器与系统内存速度之间不断加大的差距,处理器速度每年大约提高50%,而DRAM存取速度每年仅提高5%,由于性能不匹配程度的加剧,CPU将增加第三级,甚至第四级高速缓存。
4、高速缓存的构成
目前Cache基本上都是采用SRAM存储器,SRAM是英文Static RAM的缩写,它是一种具有静志存取功能的内存,不需要刷新电路即能保存它内部存储的数据。不像DRAM内存那样需要刷新电路,每隔一段时间,固定要对DRAM刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,但是SRAM也有它的缺点,即它的集成度较低,相同容量的DRAM内存可以设计为较小的体积,但是SRAM却需要很大的体积,这也是目前不能将Cache容量做得太大的重要原因。它的特点归纳如下:优点,节能、速度快,不必配合内存刷新电路,可提高整体的工作效率。 缺点,集成度低,相同的容量体积较大,而且价格较高,少量用于关键性系统以提高效率。
二、CPU 高速缓存的发展历史
高速缓存最初应用在CPU领域,目前在CPU领域的应用也最为广泛和深入。下面就简单谈谈高速缓存随CPU的发展而不断变化的历史过程。
1、80486开始出现了内部Cache
PC在诞生的初期并不存在Cache的概念,由于CPU主频很低,DRAM的存取时间甚至快于CPU存取时间,因此无需Cache。 80386时代开始出现了外部Cache。在80486时代CPU内部才正式出现了Cache。实际上80486就是由更高主频的80386 加80387数字协处理器以及8kB 内部Cache构成。80486芯片内由8kB的Cache来存放指令和数据。同时,80486也可以使用处理器外部的第二级Cache,用以改善系统性能并降低80486要求的总线带宽。
2、Peutium时代Cache技术发展迅速
Peutium不仅分离L1 Cache和L2 Cache ,而且由于Pentium处理器采用了超标量结构双路执行的流水线,有2条并行整数流水线,处理器也需要对命令和数据进进双倍的访问。为使这些访问不互相干涉,Intel把在486上共用的内部Cache,分成2个彼此独立的8kB代码Cache和8kB数据Cache,这两个Cache可以同时被访问。这种双路高速缓存结构减少了争用Cache所造成的冲突,提高了处理器效能。Pentium的Cache还采用了回写写入方式,这同486的贯穿写入方式相比,可以增加Cache的命中率。此外,还采用了一种称为MESI高速缓存一致性协议,为确保多处理器环境下的数据一致性提供了保证。在Pentium MMX中更是增大了L1的容量,并改进了相关的算法。
3、Pentium Pro出现内嵌式L2 Cache
为使Pentium Pro的性能超过Pentium,必需使用创新的设计方法,Pentium Pro使用了内嵌式L2 Cache,大小为512kB。此时的L2已经用线路直接连到CPU上,好处就是减少了对L1 Cache的需求。L2 Cache与CPU同步运行。当L1 Cache不命中时,立刻访问L2 Cache,不产生附加延迟。为进一步减少因要访问的信息不在高速缓冲中时所带来的性能损失,Pentium Pro的L1和L2都设计成非锁定型。即当哪个Cache中没有CPU所需的信息时,它不妨碍后面访问Cache的处理过程。但限于当时的CPU制造工艺,Pentium Pro的内嵌式L2 Cache 良品率太低,生产成本过高, Pentium Pro成为一款寿命短暂的过渡产品。
4、PentiumⅡ的双重独立总线
PentiumⅡ是Pentium Pro的改进型,具有MMX指令,使用动态执行技术,采用双独立总线结构。PentiumⅡ同样有2级Cache,L1为32kB(指令和数据Cache各16kB)是Pentium Pro的一倍。L2为512kB。
Pentium Ⅱ与Pentium Pro在L2 Cache 的不同主要在于L2 Cache已不在内嵌芯片上,而是与CPU通过专用64位高速缓存总线相联,与其它元器件共同被组装在同一基板上,即“单边接触盒”上。双独立总线结构就是:L2高速缓存总线和处理器至主内存的系统总线, PentiumⅡ处理器可以同时使用这两条总线,与单一总线结构的处理器相比,该处理器可以进出两倍多的数据。
5、PentiumⅢ L2 Cache进一步改进
PentiumⅢ也是基于Pentium Pro结构为核心,在原有MMX多媒体指令的基础上,又增了70多条多媒体指令。它使用动态执行技术,采用双独立总线结构。 PentiumⅢ具有32kB非锁定L1 Cache和512kB非锁定L2 Cache。L2可扩充到1~2MB,具有更合理的内存管理,可以有效地对大于L2缓存的数据块进行处理,使CPU、Cache和主存存取更趋合理,提高了系统整体性能。在执行大数据流量程序时,高效率的高速缓存管理使PⅢ避免了对L2 Cache的不必要的存取。由于消除了缓冲失败,多媒体和其它对时间敏感的操作性能更高了。对于可缓存的内容,PⅢ通过预先读取期望的数据到高速缓存里来提高速度,这一特色提高了高速缓存的命中率,减少了存取时间。
三、其他配件中的高速缓存
Cache从本质上说是一种高速设备和低速设备的速度匹配技术,不仅用在提高CPU对内存的读写速度上,而且在电脑的其它配件中也得到了广泛应用。在较慢速的其它外围设备和内存的数据交换中,甚至在网络通讯中,都需要使用Cache技术。推而广之,凡是在传输速度有较大差异的设备之间,都可以利用Cache的速度匹配技术。
1、主板高速缓存
由于在Pentium II推出之前,CPU只有内部集成的L1 Cache(一级高速缓存),L2Cache(二级高速缓存)都被放置在主板上。Pentium时代的主板上大都用速度较快,容量较大的同步PB SRAM (Pipeline Burst SRAM 管线突发式静态内存),一般为256KB或512KB。当时在主板上还存在Tag SRAM的概念。
Tag SRAM,即标记的静态随机存取存储器,它是在高速缓存系统中配合高速缓存的附加SRAM,它也是高速缓存,只是用在高速缓存电路中记录地址数据,当CPU要读取主存某一个地址中的数据时,会先到高速缓存电路中去寻找,对高速缓存系统的Tag SRAM所记录的地址数据进行搜寻和对比,当高速缓存内也存有此地址的数据时,高速缓存总线的仲裁控制电路即将数据读取传回CPU,若对比Tag SRAM记录的地址数据而找不到此数据的地址时,CPU就会到主存读取数据。因此Tag SRAM与高速缓存的命中率有很大关系。由于现在CPU内部都集成了L2 Cache,故PII以后,主板上都不再集成Cache了。
2、CPU高速缓存的应用
关于CPU高速缓存的发展历史等相关情况,前面已经谈及。这里主要介绍一下目前主流CPU使用高速缓存的情况。
象最新的Northwood P4处理器,不仅采用了0.13 微米工艺生产,其体系结构也有所改变,提高了运算效率(指令周期)。 并且将L2 CACHE的容量由老P4的256K 增加为512K。在性能上有10%左右的提升。
Tualatin 赛扬的二级缓存采用了全速256KB(8路), Pentium III同样大小的二级缓存,这对于提高CPU的性能有很大的帮助。Tualatin核心赛扬的性能非常不错,在很大程度上就是得益于256KB的全速缓存。这也充分反映出高速缓存对电脑配件性能的影响。
AMD 的Morgan实际上和Palomino核心的毒龙规格相同,只是CPU内部L2 Cache有所不同。最引人注意的一点是改进了Cache算法。在Morgan中包含了一个硬件化的数据预读取规则。这个功能就是在CPU对数据进行了处理之后,预读取设备可以猜测哪些数据是CPU所需要的。如果这些数据并没有在Cache中,那么这个预读取设备就会自动到主内存中去重新获取这个数据;而如果这个数据已经存在于Cache之中的话,那么CPU就会更加快速地得到这个数据。
Athlon XP无疑是AMD今年最成功的产品,它采用了类似于Pentium 4的硬件预读技术--执行跟踪高速缓存,预先将处理器可能需要的数据从主内存读到缓存中,这一过程能明显提高系统总线和内存带宽的利用率,进而提升系统性能。
主要用于服务器的Merced 对Cache的要求更高了。为此,lntel在芯片内开发新的Cache,并增加L1 Cache的容量,来平衡CPU和DRAM间的速度。为此,在Merced的片上最接近执行单元旁再设另一处Cache,称为L0缓存,是指令/数据分离型。由于L0Cache在物理位置上比L1离执行单元更近,布线距离的缩短,使它与执行单元间的数据交换速度比L1还快,可以进一步提高工作主频。 同时,还要在芯片内部配置超过1MB的大容量L1 Cache。芯片内部Cache比外部Cache更易于提升与执行单元间的数据传送速度。
3、硬盘高速缓存
在PC的磁盘系统中,高速缓存也得到了广泛应用。为提高内存对硬盘的读写速度,就要建立磁盘高速缓存,不过硬盘高速缓存不必使用昂贵的SRAM,使用普通的DRAM即可,因为DRAM内存的存取速度对CPU来说较慢,但对磁盘的存取速度却是很快的。这是因为磁盘存储系统包含有磁头的机械运动,而机械运动无法跟传送电信号的电子速度相比。以前硬盘内部集成的高速缓存只有512K左右,而现在硬盘普遍将高速缓存的容量提升到2M以上,个别产品甚至达到了8M。由于硬盘Cache无需使用高速的SRAM,除了内部集成的SDRAM,我们还可以在系统主内存中划出一个区域,作为专用的磁盘缓冲区,采用一定的数据结构,即可实现磁盘存取的二级Cache技术。硬盘高速缓存的工作过程及原理与CPU高速缓存类似,也是把即将访问的数据整块地拷贝到高速缓存区中,然后内存再到高速缓存中去逐个读取数据。由于数据在RAM空间内部传送要比在RAM与磁盘间传送快得多,从而系统由此提高了存取速度。
下面给大家介绍一下西数WD1000BB-SE 8MB缓存硬盘,由于内存的读写速度大大高于硬盘的读写速度,因此大容量的缓存可以有效提高存储器的数据传输速度。但目前市面所售的大部分硬盘都只带512K--2MB的缓存。西数前段时间推出的7200转,100G硬盘特别版WD1000BB-SE,其单碟容量为33G,接口类型为ATA100,平均寻道时间8.9毫秒,这方面参数与其他硬盘相比并无特别,不过WD1000BB-SE将硬盘的缓存容量从2MB直接提升到了8MB。引起了业界的普遍关注。经过多方面评测,由于缓存容量的加大,这款IDE接口硬盘的实际性能已经接近或超越了不少10000转SCSI接口硬盘,成为IDE硬盘中的速度王者。这也充分反映出高速缓存对电脑配件性能的影响。
4、刻录机的缓存
缓存容量的大小是衡量光盘刻录机性能的重要技术指标之一,刻录时数据必须先写入缓存,刻录软件再从缓存区调用要刻录的数据,在刻录的同时后续的数据再写入缓存中,以保持要写入数据良好的组织和连续传输。如果后续数据没有及时写入缓冲区,传输的中断则将导致刻录失败。因而缓冲的容量越大,刻录的成功率就越高。市场上的光盘刻录机的缓存容量一般在1MB~4MB之间,目前最大的有8M缓存的产品。尤其对于IDE接口的刻录机,缓存容量很重要。增加高速缓存既有利于刻录机的稳定工作,同时也有利于降低CPU的占用率。 总之缓存大小对刻录机是非常的重要的,缓存越大刻录时就越稳定。目前市场上有多款刻录机都带有8M缓存,配合其他防刻死技术,有效防止了出现“缓存欠载”导致刻录失败的问题。
在普通光驱中也内置有高速缓存,当然其作用没有刻录机中的重要,主要是为了提高读盘效率,降低CPU占用率,因此容量也比较小,一般只有512K。
5、其他设备的高速缓存
在PC其他配件中也都存在高速缓存的应用。比如在显示系统中,由于3D应用的迅猛发展,现在显卡上的显示内存普遍达到了32M以上,甚至多达128M,因此也广泛使用着高速缓存技术,如前台缓存、后台缓存、深度缓存和纹理缓存等。
现在还有所谓CDRAM(Cache DRAM) 带高速缓存的内存,就是在内存芯片上集成了特殊构造的SRAM。发展好的话过几年有可能成为主流内存。除此之外,甚至在声卡、RAID卡、SCSI卡中也带有高速缓存,
四、高速缓存的调整及应用
1、BIOS中与高速缓存有关的选项
1)Video ROM的Shadow
“影子”内存(ShadowRAM,或称ROMShadow)是为了提高系统效率而采用的一种专门Cache技术,它把系统主板上的系统ROMBIOS和适配器卡上的视频ROMBIOS等拷贝到系统RAM内存中去运行,其地址仍使用它们在上位内存中占用的原地址。更确切地说,是从扩展内存中拿出一部分物理存储空间,而赋以ROM的原地址,由这部分扩展RAM代替原ROM。由于ROM采用静态CMOS电路,其存取速度为200ns左右,而系统存储器RAM采用动态CMOS电路,其存取速度进几十ns,速度快好几倍,将存放在ROM中的BIOS代码(基本输入输出例行程序,它们在系统运行期间非常频繁的被调用)拷贝到系统RAM中去,就可提高系统运行和显示的速度和效率。
2)CPU Internal Cache
CPU内部快速缓存是否打开,一般设置为Enable。Enternal Cache:是否使用主板缓存,一般设置为Enable。CPU L2 Cache Ecc Checking:CPU的L2 缓存Ecc 检测,可设置为Disable。
从字面上看,“CPU Internal Cache”和“External Cache”分别指CPU内部和外部的高速缓存,但更准确的说法应该是一级缓存和二级缓存。Socket/Super 7架构的CPU内部只有一级缓存,二级缓存放在了主板上,“Internal”和“External”的说法就源于此,而对PⅡ、PⅢ和K6-Ⅲ等CPU来说,二级缓存也被集成到CPU内部,内外部的说法就不太确切了,因此一些Slot 1主板对此进行了修改,改称为“CPU Level 1 Cache”和“CPU Level 2 Cache”。除非打开后系统会出现死机等情况,否则这两个选项都应设为Enabled,以加快CPU读取内存的速度。
3)二级缓存的潜伏期
在BIOS中,我们还可以调节二级缓存的潜伏期,其中Level 2 Cache Latency(二级缓存潜伏期)有16个值可选(1~15),从理论上来说,数值越小延迟时间越短,性能也越高。如果把数值设得过小,二级缓存有可能停止工作,不仅系统性能会急速下跌,还会发生死机现象。L2 Cache对内存带宽有重大影响,即使CPU频率再高,其它设备跟不上亦是无用,增加缓存潜伏期可以让机器更稳定,避免上述情况。
4)System BIOS Cacheable
“System BIOS Cacheable”、“Video BIOS Cacheable”和“Video RAM Cacheable”分别指定是否可以使用二级高速缓存来缓存系统BIOS、显卡BIOS和显示内存,缓存之后,BIOS调用的执行速度以及访问显示内存的速度都会加快,因此最好都设成Enabled。不过,当显示内存可以被缓存时,少数显卡可能会出现兼容性问题,此时可考虑将第三项设为Disabled。
2、调整高速缓存优化系统
如果你的应用程序需频繁访问硬盘,可在扩充或扩展内存中建立“直接写盘(write-through)”型磁盘高速缓存。用户可在autoexec.bat文件中加入命令行:c:\dos\smartdrv.exe,则此驱动程序会自动装入内存高端,其磁盘缓冲区缺省值为256KB,你可以改变这个值的大小。一般设置为物理内存的1/8左右比较合适。SMARTDRV.EXE一个外部设备驱动程序。用此程序可启动或设置磁盘高速缓冲存储器。与Cache不同,Cache是充分发挥了CPU的速度,而SMARTDRV是加快了磁盘的读写速度。在实际应用中,SMARTDRV.EXT高速缓存驱动程序将记住每次应用程序使用磁盘的磁盘扇区数据,不用再访问磁盘驱动器,而是访问内存中已包含这些数据的区域。
总的来说,PC中的Cache主要是为了解决高速设备和低速设备间速度匹配的问题,是提高系统性能,降低系统成本而采用的一项技术。随着电脑技术的飞速发展, Cache已成为PC中大多数配件不可缺少的组成部分,是衡量系统性能优劣的一项重要指标。从系统的性价比考虑,Cache的配备将在很长一段时间内仍然是PC中重要的技术之一。
D. 缓存一致性
在现代的 CPU(大多数)上,所有的内存访问都需要通过层层的缓存来进行。CPU 的读 / 写(以及取指令)单元正常情况下甚至都不能直接访问内存——这是物理结构决定的;CPU 都没有管脚直接连到内存。相反,CPU 和一级缓存(L1 Cache)通讯,而一级缓存才能和内存通讯。大约二十年前,一级缓存可以直接和内存传输数据。如今,更多级别的缓存加入到设计中,一级缓存已经不能直接和内存通讯了,它和二级缓存通讯——而二级缓存才能和内存通讯。或者还可能有三级缓存。
缓存是分“段”(line)的,一个段对应一块存储空间,大小是 32、64或128字节,每个缓存段知道自己对应什么范围的物理内存地址。
当 CPU 看到一条读内存的指令时,它会把内存地址传递给一级数据缓存。一级数据缓存会检查它是否有这个内存地址对应的缓存段。如果没有,它会把整个缓存段从内存(或者从更高一级的缓存,如果有的话)中加载进来。是的,一次加载整个缓存段,这是基于这样一个假设:内存访问倾向于本地化(localized),如果我们当前需要某个地址的数据,那么很可能我们马上要访问它的邻近地址。一旦缓存段被加载到缓存中,读指令就可以正常进行读取。
如果我们只处理读操作,那么事情会很简单,因为所有级别的缓存都遵守以下规律—— 在任意时刻,任意级别缓存中的缓存段的内容,等同于它对应的内存中的内容。 。
一旦我们允许写操作,事情就变得复杂一点了。这里有两种基本的写模式:直写(write-through)和回写(write-back)。直写更简单一点:我们透过本级缓存,直接把数据写到下一级缓存(或直接到内存)中,如果对应的段被缓存了,我们同时更新缓存中的内容(甚至直接丢弃),就这么简单。这也遵守前面的定律: 缓存中的段永远和它对应的内存内容匹配。
回写模式就有点复杂了。缓存不会立即把写操作传递到下一级,而是仅修改本级缓存中的数据,并且把对应的缓存段标记为“脏”段。脏段会触发回写,也就是把里面的内容写到对应的内存或下一级缓存中。回写后,脏段又变“干净”了。当一个脏段被丢弃的时候,总是先要进行一次回写。回写所遵循的规律有点不同。 当所有的脏段被回写后,任意级别缓存中的缓存段的内容,等同于它对应的内存中的内容。
换句话说,回写模式的定律中,我们去掉了“在任意时刻”这个修饰语,代之以弱化一点的条件:要么缓存段的内容和内存一致(如果缓存段是干净的话),要么缓存段中的内容最终要回写到内存中(对于脏缓存段来说)。
只要系统只有一个 CPU 核在工作,一切都没问题。如果有多个核,每个核又都有自己的缓存,那么我们就遇到问题了,因为如果一个 CPU 缓存了某块内存,那么在其他 CPU 修改这块内存的时候,我们希望得到通知。系统的内存在各个 CPU 之间无法做到与生俱来的同步,我们需要一个大家都能遵守的方法来达到同步的目的。
缓存一致性协议有多种,但是日常处理的大多数计算机设备使用的都属于“窥探(snooping)”协议。
窥探”背后的基本思想是,所有内存传输都发生在一条共享的总线上,而所有的处理器都能看到这条总线:缓存本身是独立的,但是内存是共享资源,所有的内存访问都要经过仲裁(arbitrate):同一个指令周期中,只有一个缓存可以读写内存。窥探协议的思想是,缓存不仅仅在做内存传输的时候才和总线打交道,而是不停地在窥探总线上发生的数据交换,跟踪其他缓存在做什么。所以当一个缓存代表它所属的处理器去读写内存时,其他处理器都会得到通知,它们以此来使自己的缓存保持同步。只要某个处理器一写内存,其他处理器马上就知道这块内存在它们自己的缓存中对应的段已经失效。
在直写模式下,这是很直接的,因为写操作一旦发生,它的效果马上会被“公布”出去。但是如果混着回写模式,就有问题了。因为有可能在写指令执行过后很久,数据才会被真正回写到物理内存中——在这段时间内,其他处理器的缓存也可能会傻乎乎地去写同一块内存地址,导致冲突。在回写模型中,简单把内存写操作的信息广播给其他处理器是不够的,我们需要做的是,在修改本地缓存之前,就要告知其他处理器。
MESI 是四种缓存段状态的首字母缩写,任何多核系统中的缓存段都处于这四种状态之一。
从CPU读写角度来说:
上图的切换解释:
缓存的一致性消息传递是要时间的,这就使其切换时会产生延迟。当一个缓存被切换状态时其他缓存收到消息完成各自的切换并且发出回应消息这么一长串的时间中CPU都会等待所有缓存响应完成。可能出现的阻塞都会导致各种各样的性能问题和稳定性问题。
比如你需要修改本地缓存中的一条信息,那么你必须将I(无效)状态通知到其他拥有该缓存数据的CPU缓存中,并且等待确认。等待确认的过程会阻塞处理器,这会降低处理器的性能。因为这个等待远远比一个指令的执行时间长的多。
为了避免这种CPU运算能力的浪费,Store Bufferes被引入使用。处理器把它想要写入到主存的值写到缓存,然后继续去处理其他事情。当所有失效确认(Invalidate Acknowledge)都接收到时,数据才会最终被提交。
执行失效也不是一个简单的操作,它需要处理器去处理。另外,存储缓存(Store Buffers)并不是无穷大的,所以处理器有时需要等待失效确认的返回。这两个操作都会使得性能大幅降低。为了应付这种情况,引入了失效队列——对于所有的收到的Invalidate请求,Invalidate Acknowlege消息必须立刻发送,Invalidate并不真正执行,而是被放在一个特殊的队列中,在方便的时候才会去执行,处理器不会发送任何消息给所处理的缓存条目,直到它处理Invalidate。
E. 缓存一致性协议
锁缓存行有一套协议叫做 缓存一致性协议 。缓存一致性协议有MSI、MESI、MOSI、Synapse、Firefly以及DragonProtocol等等。
MESI分别代表缓存行数据的4中状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的
假设有三个CPU-A、B、C,对应三个缓存分别是cache-a、b、c。在主内存中定义了x的引用值0
单核读取
MESI优化和引入的问题:各CPU缓存行的状态是通过消息传递来进行的。如果CPU0要对一个在缓存中共享的变量进行写入,首先需要发送一个失效的消息给到其他缓存了该数据的CPU,并且要等到他们的确认回执。CPU0在这段时间内都会一直处于阻塞状态,会导致各种各样的性能问题和稳定性问题。
为了避免阻塞带来的资源浪费,在CPU中引入了Store Buffer。
CPU在写入共享数据时,直接把数据写入到Store Buffer中,同时发送Invalidate消息,然后继续去处理其他指令。当收到其他所有CPU发送了Invalidate Acknowledge消息时,再将Store Buffer中的数据存储到Cache Line中,最后再从Cache Line同步到主内存。
F. EMSI协议
翻译至 https://en.wikipedia.org/wiki/MESI_protocol
EMSI是基于缓存无效化的一致性缓存协议,并且是一种最常见的支持回写式缓存的协议。它也被称为伊利诺伊州协议(由于其在伊利诺伊大学厄本那香槟分校被开发)。回写式缓存和写入式缓存相比可以节约很多的带宽。回写式缓存经常会存在脏状态,而脏状态表明了高数缓存中的数据与主存中的数据不一致。EMSI要求当缓存未命中时并且别的缓存中有该数据,那么缓存和缓存间应该互相传输数据。MESI相对与MSI来说降低了与主存的交互次数,这带来了显着的性能提升。
MESI的四个字母分别代表了四个可以被标记在缓存行上的独立状态。(也就是用2bit来编码)
当缓存行处于Modified状态时,它表明该缓存行只存在于当前缓存中。并且这个缓存行中的数据是脏数据,也就是说这个缓存行中的数据与主存中的数据不一致。缓存被要求在未来将缓存行的数据写于主存中,但不用立即写入。但如果别的缓存向该缓存请求这个数据,那必须保证该数据写入主存已经完成。当回写回主存完成后,缓存行状态会有Modified变为Shared状态。
当缓存行处于Exclusive状态时,它表明该缓存行只存在于当前缓存中,不过其中的数据与主存中的数据是一致的。当别的缓存向该缓存请求read当前缓存行时,缓存行状态会变成Shared。或者当有write操作时,他会变成Modified状态。
当缓存行处于Shared状态时,它表明该缓存行可能同时存在与别的缓存中,并且其中的数据与主存中一致。这个缓存行随时可能被丢弃(改变为Invalid状态)。
当缓存行处于Invalid 状态时,表明该缓存行是无效的。
对于给定的两个缓存,以下是允许共同存在的状态:
当一个缓存中的变量被标记为M状态,那同样拥有这个变量的别的缓存的缓存行会被标记为Invalid。
从一个状态到另一个状态的转变有两个重要影响因素。第一个因素是处理器发出了特殊的读写请求。举个栗子:处理器A的缓存中有变量X,然后这个处理器向自己的缓存发送了对于这个变量的读写请求。第二个影响因素是来自别的处理器的请求,这些处理器缓存中没有这个变量,或者它们想要更新这个变量。这些总线请求被一个名叫Snoopers的监听器监听着。
下面解释不同种类的处理器请求和总线请求
处理器请求包括如下两种:
总线请求包括如下五种:
如果从主存中获取一个值需要等待的时间比通过缓存间传值等待的时间长,那么我们就可以说缓存间传值可以降低缓存未命中后的读延迟。在多核架构下,一致性主要在二级缓存间保持,但处理器仍然有三级缓存,从三级缓存中获取未命中的变量往往快于从二级缓存。
监控操作 :
所有缓存中的变量都拥有四种状态的有限状态机。
对于不同输入的状态转换关系和回复如下表1.1和1.2
只有写操作发生在Modified或Exclusive状态的缓存行时,才缓存才不需要做额外操作。如果状态为Shared的缓存行被写入,那么首先别的缓存需要无效它们的缓存行。这个由一个叫 Request For Ownership (RFO) .的广播操作执行。
当一个变量为Modified时,这个缓存必须监听所有别的缓存对于该变量对应主存的读请求,一旦监听到就必须将这个变量写入主存。这个过程可以通过强制让别的缓存等待的方法来完成。当完成了对主存的写入,状态变为Shared。但同样可以直接通知别的缓存这个变量的值,而不写入主存。
当处于Shared状态时,必须监听所有的rfo广播,一旦收到就让缓存中的变量无效。
Modified和Exclusive状态是精确的,当有缓存行处于这个状态就表明,这个变量是这个缓存独有的。而Shared状态时不精确的,当别的缓存丢弃了这个Shared状态的缓存行,那么可能只存在一个缓存行状态为Shared但它不会变为Exclusive。丢弃Shared状态行不会引起别的缓存的注意。
使用Exclusive可以带来性能上的提升,因为修改Exclusive不需要通知别的缓存,而修改Shared状态的缓存行需要告诉别的缓存,并使这些缓存行无效,这是耗时的。(这也是EMSI与MSI协议的区别)
MESI简单直接的实现存在着两个性能问题。1.当向一个Invalid的缓存行写入时,需要从别的缓存获取值,这是很耗时的。2.需要将别的缓存行的该值设置为Invalid这也是耗时的。为了解决这两个问题,我们引入了存储缓冲区和无效化队列。
当向一个无效的缓存行写入时会用到储存缓冲区。因为这个写操作最终一定会被执行,因此CPU发送读无效消息(让别的缓存中的该缓存行无效)并且将要写入的值放到存储缓存区中,当这个需要的缓存行写入缓存时,存储缓存区中存储的值将被执行写入。
存储缓存区存在带来的后果是,当一个CPU进行写操作,值不会立即写入缓存中。因此,无论何时CPU读取缓存中的值时,都需要先扫描自己的存储缓冲区,确保缓冲区中是否还有未写入的值。值得注意的时不同CPU之间存储缓冲区时不可见的。
当CPU收到无效请求时,它会将这写无效请求放入无效化队列中。放入队列中的请求会被迅速执行但不是立即执行。所以CPU可以忽略它的缓存块是无效的。CPU不能扫描它的无效队列,这是和存储缓冲区的区别。
可见存储缓冲区带来的是写不同步,而无效化队列则带来读不同步,为了解决这些不同步,我们需要内存屏障。写屏障会刷新我们的存储缓冲区,确保里面所有的写都会被执行到这个CPU的cache上,而读屏障可以保证所有无效化队列里的任务都被执行,确保别的CPU的写对自己可见。
G. 为什么mesi协议能够解决多处理机系统中的cache一致性
纵观PC系统和CPU二十年的发展,随着半导体加工工艺水平的不断提高,CPU和存储器的性能都有了很大的提高。 CPU频率的提高,必然要求系统中存储器的存取速度要提高,还要求其容量要增大。
MESI(Modified Exclusive Shared Or Invalid)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出)是一种广泛使用的支持写回策略的缓存一致性协议
H. 救救我,感激不尽,若能挺过这一关,做牛做马都愿意
熔点在Reichart Thermover热阶段放大获得的。使用Pye Unicam SP- 光谱仪,用溴化钾光盘记录红外光谱。C和H的元素则使用Heraeus CHN - O型快速仪分别完成。质谱记录采用Finnigan Matt 型质谱仪,在电离势为70e下操作。'H和13C核磁共振谱在.94和75.43兆赫分别录得,使用arian 兆赫仪器以CDC13作为溶剂和MeSi(伊利诺斯协定?)作为内部存储标准。31P 核磁共振谱是使用相同的仪器以CDCl31和加入外部磷酸(D20的85%)在21.42兆赫下测定的。工作中使用的试剂和溶剂是由Fluka(布克斯,瑞士)获得的。
属于专业解释,你要自己理解部分:
第一句,好像句子不全或者Microscope有误。 Reichart Thermover是德文或者俄文标志的生产厂的加热仪器,但是也有一种德国产的化学品中出现。
保留所有外文仪器名称,因为是非英文,德文?
Me$i解释为Illinois Protocol缓存和内存一致性的协议,
来世?这些就过时了,没人再为它烦恼了。