现在的位置: 首页 > 综合 > 正文

【 我所認知的BIOS】–>Cache(3)

2013年10月08日 ⁄ 综合 ⁄ 共 4767字 ⁄ 字号 评论关闭

 我所認知的BIOS-->Cache(3)

LightSeed

12/14/2009

Go on。。。这章详细讲cache的操作过程。

 

9、详细剖析memory的读操作

下面的一系列的演示是在486的基础上,并且L1 read miss的情况下。好,我们来开始:

Processor在执行

MOV AL,[4025]

加上processor正处于保护模式或者实模式,并且segment是从0开始的,页管理方式已经关掉。那么我们可以这样理解上面这个指令,就是processor要准备从内存地址为00004025处的数据读一个byte出来,并存到AL当中去。

9.1 L1 cache的角度来看main memory

Cache controller486上的话必须要去考虑4G大小的内存空间。486L1 cache controller把内存空间分成了2097152个页(这个页和讲虚拟存储机制中的页两回事哦。)而且每个页大小是5KBCache controller还把这每个page都均分成了128line,每个line的大小一下就算出来了是16bytes(这就是前文提到的“不太大的一块数据”),line的序号是从0~127

举个例子,内存地址从00000000~00000000FH的内存数据应该属于是page 0line 0的地方。00000010~00000001FH的内存数据应该属于是page 0line 0的地方,以此类推。当processor产生一个内存地址的时候,高21位(A31:A11)是用来确定2KB page的,接着的7位(A10:A4)是用来确定这个pageLine的。剩下的最低4位是用来确定这里line中的具体位置。

那么来看看我们例子中的内存地址,00004025H,用这种方法来计算的话,mov指令应该尝试着去读取第8 page的第2 line的第5位置处的数据。

9.2 L1响应memory read的请求

物理内存的地址00004025H传递到L1 cache controller后,L1 cache controllercheck自己的目录里面是不是有这个内存中的数据。如果数据在L1 cache里面的话,那么L1就迅速地放回数据给processor。如果数据不在L1 cache中的话,那么L1 cache controller就会产生一个read周期的请求到总线上。

9.3 L1 cache controller的结构

L1 cache controller的结构如图3

3 L1 cache controller的结构

 

从图3中可以看出,在cache的存储器中有4bank,一般命名为way0~way3。每个bankway)是由2KB的高速静态RAM组成。这2KBSRAM被分成了128Line0~127)。每个line能够存储16bytes的数据。当一个16 byte的数据从外部存储器中读到cache controller中的时候,会被存到4bank中某个bank的某个Entry里面去。不过,这里对应的Entry是专属的。举个例子,任何一个memory page中的 line 12的数据都会被放到bank中的Entry 12处。

让我们来看看图3,一个一个来说其中的作用吧:

LRU,这个就是least recently used,它是供LRU算法计算用的标记。(后面我会详细说明。)

Tag valid bits,它是标记后面的tag field是否有效的。在cache controller check的过程中,会首先看这个bit。如果无效的话,那么根本不用看了。如果有效的话,那么通过比对知道,line中的数据是从哪个内存地址copy过来的数据。

Tag fields,它本身在entry(条目)中所处的位置和自己这个区段存储的数据结合起来就表示了他对应的实际的物理内存地址(physical memory address)。见图3的最下方,[A31:A11]代表了是从page 8中来的数据,[A10:A4]表明了是从line 2中来的数据。而存储的数据就在bank中的line 2里面。(那么你现在知道图3中,tag fields 0~3中所对应的数据,对应的物理地址是多少么?)

如果在cache controllercheck page address的时候,没有tag fields与之匹配,那么cache miss就发生了。Controller就会触发一个read的请求到bus上,以此希望能从外部的存储器得到数据。当数据从外部的存储器读回来的时候,controller必须要把数据保存起来,并且更新目录条目。如果当前的4line都是被使用的,那么controller就必须要去裁定哪个是最旧的数据,然后用新的数据覆盖它。与此同时目录条目(directory entry)和LRU标记都要更新。这种情下,controller就是用LRU的标记来做判断的。

9.4 L1 cachecheck

4L1 cache解析内存地址的一个示意图,见图4再回味一下上节Tag field的说明就可以更清楚了。

 

 

4

9.5 The bus cycle request

read miss发生的时候,L1 cache controller触发一个memory read 的系统周期请求到处理器的总线单元上去。作为回应,总线单元(bus unit)会触发一个memory read的总线周期(bus cycle)。486 processor会屏蔽掉地址的最低两位,因为processor没有A0A1这两个输出。这是因为内存地址会被转换成双字(double word)来读取。比如说,在操作00004025H的时候,会把地址转换成00004024H处的地址,但是会bus unit会把BE1#使能,这样就可以确定从00004024H开始的双字的第二个位置作为目标位置。图5是当前的内存地址输出的信号。

 

 

5 00004025H的内存地址信号输出

6总线周期的时序图。看看图6中的第二周期,当00004025H地址被放到地址总线上时,双字地址当然应该是00004024H,从00004024H开始处的4byte00004024~00004027H这四个内存地址处的数据。因为执行单元只需要00004025H中的数据,(仅仅需要第二个byte),这就体现在BE1#被使能上。Processor同时会把PCD(page cache disable)输出拉低,(表明,现在是有cache的)。那么L2的存储系统就必须要考虑内存地址是cacheable的情况,应该要接收整个line里的信息。(16 bytes哦,所以才会有4020~402C这么多地址的信息,不过可能有人会问,为什么是先传00004024H开始的double word呀?这是和line fill的机制有关的,后面稍微讲讲。)假如说,processorPWTpage write through)代表着更新cache的方式。(也就是前面我们所说的WBWT两者的区别。)当PWT为低的时候,表示write back controller在更新cache的同时,不需要同时更新主存。当write miss的时候processor就得把数据写入到主存中去。反之(PWT为高)就是write-back controller在更新它的cahce的时候同时也更新主存。如果write miss的话,那么就只更新主存。

 

 

6 总线周期的时序图

其实在第一次或者说第N次读这个图的时候,对于图中的两个wait state总是感觉理解的不够深入。这里也详细说明一下,为什么会有这两个状态,并且他们的作用是什么。

先说说第一个wait stateCLK 4其实后面的一个wait 也是一样的。至于为什么要间隔开,到目前为止,我的理解是因为486能够锁存的数据是64bit,如果是128bit的话,就应该能一次(不用再插入wait的状态)全部传输完了。),processor采样RDY#BRDY#check需要读取的data是否再数据总线上。当BRDY#(笔者:从某种程度上说,BRDY#的信息对于CPU更有效。)采样有效后,这就告诉了processor两件事:

①第一个doubleword16bytes分成4double word来传送。)已经在数据总线上了。

memory的地址传送支持bursting这种机制。

Processor作为回应应该是这样:

①读取总线上的第一个doubleword下来,并存到L1 cache的存储器中去。当然这个信息是不会被L1记录下来的。只有等到整个line都被填满了后才会把这个信息记录下来。

②确定本来processor想要的数据。(比如说00004025H处的数据。)执行单元会把这个byte的数据放到AL寄存器中去,这才是真正的MOV指令哦。呵呵。。。

③突发传输(burst)第二个doubleword,(地址是00004020H)。

9.6 怎么去填cacheLine

正如前面所说,当L1 cache miss发生了以后,processor把内存地址放到地址总线上去,并且把PCD拉低来表明马上要执行填L2 cachelineNCA逻辑部件也是内存地址解析的一个重要部分,每次机器上电后,NCA逻辑部件都会自动地被设置成non-cacheable的属性。当NCA逻辑部件检测到总线上的内存地址是cacheable的时候,它就得在地址周期(address timeT1))结束前把KEN#Cache enable)信号拉低。只有这样做了,才能表明memory已经同意填line的信息。Processor必须在CLK的上升沿的时候采样KEN#信号,接着在下一个CLK上升沿采样RDY#或者BRDY#信号。

在我们的例子中,从图6中可以看出,当从00004024H的内存地址读取一个双字的的时候,在第一个总线周期(bus cycle)中插入了一个wait的状态。我们假设00004025H的内存地址是cacheable的情况下,processor会在地址周期的最末,采样KEN#信号(low)。当在下一个CLK周期的上升沿采样到BRDY#的时候,说明processor的地址系统已经同意执行cache line fill的操作了。

9.7 cache line fill defined

刚刚一直在说line fill,可是它究竟是个啥呢?是怎么定义的呢?

每当cache controller发生read miss的时候,processor就必须要经过L2 cache controller到速度比较慢的主存中去read,请求data。然而在L2 读取数据的时候,却不是单独地读取某一字节或者字。由于L1cache是由Line这种东西来存储数据的,而且在486上一个line的大小为16 bytes,那么当cache从主存读取数据到line的时候,就需要操作16bytes了。

然而16bytes组成的一个block的位置都是在可以被16整除的地址界限上开始的。(比如说0H,10H,20H etc.

L2 read miss的时候,processor触发了一个memory readbus cycle。经过NCA逻辑解析后,假如这个memory addresscacheable的,那么processor就希望能够获取4double word的信息。然而这4double word却不需要送回来的顺序是已经规定好的。而这个送回来的顺序就叫做“cache line fill sequence”。这个顺序可以有以下四种,见图7(笔者:这里PCI的设备读取data的时候也有这个顺序,在操作cacheline

抱歉!评论已关闭.