高速缓冲存储器(Cache),也称为高速缓存。为了解决CPU和主存速度不匹配,使用比DRAM更快的SRAM,但容量比主存小。
因访问主存的局部性(时间、空间),现在访问主存的数据很可能将来仍会访问,现在访问主存的数据附近的数据很可能将来会访问,因此将现在访问主存的数据同时调入到Cache中。Cache中的数据是主存中数据的副本。
CPU访问Cahce的速度比访问主存的速度快,某数据若已在Cache中(命中),就无需访问主存,提高了CPU的效率。
CPU与Cache之间的数据交换以字为单位,主存与cache之间的数据交换以块为单位,Cache中块也称为行。
Cache主要由Cache存储体、地址转换部件、替换部件组成。
Cache存储体:存放由主存调入的指令与数据块。
地址转换部件:建立目录表,实现主存地址到Cache地址的转换(通过映射)。
替换部件:若Cache满了,按一定策略进行数据块替换,并修改地址转换部件。
全相联映射:主存任意块可以映射到Cache中的任意块。主存块和Cache块大小相同。
主存地址:主存块号 + 块内地址。
目录表存放在相关(联)存储器中,其中包括三部分:标记(即主存块号)、Cache块号、有效位(也称装入位)。目录表的容量与Cache的块数相同。
判断是否命中:检查所有内容(但找到,后面的就不用再检查)。有效位为1,标记与主存块号相同,则命中。若没有命中,CPU访问主存。
优点:命中率比较高,Cache存储空间利用率高。
缺点:判断是否命中时,每次很可能要与全部内容的有效位和标记比较,速度低,成本高,因而应用少。
主存中一块只能映射到Cache的一个特定的块中。主存块和Cache块大小相同。
将主存空间按Cache容量分成区(每区的块数与Cache的块数相同),因此主存块号中又分为区号和块号(与Cache块号相同,因此标记中不含此部分)。若是十进制表示,则用主存块号除以Cache总容量取余就能得到对应的Cache中的块号,而标记则为主存块号除以Cache总容量的商。
主存地址:主存块号 (区号+块号)+ 块内地址。
目录表存放在高速小容量存储器中,其中包括二部分:主存的区号和有效位。可以根据主存块号中的后n位确定Cache块号。目录表的容量与缓存的块数相同。
判断是否命中:只检查对应块号。有效位为1,标记与主存块号中的区号相同,则命中。若没有命中,CPU访问主存。
优点:地址映象方式简单,判断是否命中时,只要检查对应块号的有效位和区号,访问速度较快,硬件设备简单。
缺点:替换操作频繁,命中率比较低。
先分组,再将主存块映射到Cache中的对应组,在组内可随意放。主存和Cache的块大小相同、组大小相同。
将主存空间按Cache容量分成区,主存中每一区的组数与Cache的组数相同。因此主存块号中又分为区号和组号(与Cache组号相同,因此标记中不含此部分)。
主存地址:主存块号 (区号+组号)+ 块内地址。
目录表存放在相关(联)存储器中,其中包括二部分:主存的区号和有效位。可以根据主存块号中的后n位确定Cache组号。目录表的容量与Cache的块数相同。
判断是否命中:检查对应块号中的所有内容(但找到,后面就不用再检查)。有效位为1,标记与主存块号中的区号相同,则命中。若没有命中,CPU访问主存。
放入对应组号采用直接映射方式,按地址访问;在组内采用全相联映射方式,按内容访问。
优点:块的冲突概率比较低,块的利用率大幅度提高,块失效率明显降低。
缺点:实现难度和造价要比直接映射方式高。
Cache容量很小,若Cache满了,需要将某些行替换掉。
直接映射方式,在特定块中映射,只要特定块有数据而且是不命中,就直接替换掉。
组相联映射方式,在特定组中映射到任意块,只要特定组满了且不命中,需采用策略替换。
全相联映射方式,在Cache中映射到任意块 ,只要Cache满了且不命中,需采用策略替换。
主要替换策略有:先进先出法、近期最少使用法、最不经常使用法、随机法等。
First In First Out,FIFO。先调入Cache的先被替换掉。
简单,但命中率不高,不符合局部性规律。可能出现抖动现象,即刚被换出的块很快又被调入。
Least Recently Used,LRU。
为每个Cache块设置"计数器",记录多久没被访问了,
当命中时,命中的"计数器"清零,比它的"计数器"值小的非空的块"计数器"加1,
当不命中时,新的块的"计数器"为0,其他非空的块"计数器"加1,
当Cache满了且不命中,把"计数器"最大的块替换掉且"计数器"为0,其他非空的块"计数器"加1。
符合局部性规律,命中率高,但也可能发生抖动现象。
Cache的总块数=,则计数器需要n位,计数器的值在0到n-1之间。
Lease Frequently Used,LFU。把累计访问次数最少的替换掉。
为每个Cache块设置"计数器",记录被访问了多少次,当命中时,命中的"计数器"加1,
当Cache满了,把"计数器"最小的块替换掉,若多个最小的,可替换掉块号最小的或结合FIFO。
不是很符合局部性规律,实际应用不如LRU。
Random。随机挑选一块替换掉。简单 ,易于实现,但命中率低,不符合局部性规律。
(1-1)写回法(write-back)
若数据被修改,且已在Cache中,在替换时写回到主存。
Cache目录表中多一位“脏位”,记录是否修改过。
(1-2)全写法(write-through)
若数据被修改,且已在Cache中,同时写入Cache和主存。
一般通过写缓冲(write buffer,使用SRAM实现)写入主存。可能写缓冲会溢出。
(2-1)写分配法(write-allocate)
若数据被修改,但并未在Cache中,仍在主存中,将主存中的数据调入Cache,在Cache中修改,再写回到主存。通常搭配写回法使用。
(2-2)非写分配法(nog-write-allocate)
若数据被修改,但并未在Cache中,仍在主存中,直接在主存中修改。通常搭配全写法使用。
离CPU越近,Cache速度越快,但容量越小。
多级Cache之间,保证数据一致,常使用“全写法”和“非写分配法”;
Cache和主存之间,保证数据一致,常使用“写回法”和“写分配法”。
1、命中率:CPU访问的数据,已经在Cache中的比率。假设用H表示。
2、不命中率:CPU访问的数据,不在Cache中的比率。假设用M表示,M=1-H。
3、平均访问时间:命中率*访问Cache的时间+不命中率*访问主存的时间。