1.Cache简介
同样是基于程序访问的局部性,在主存和CPU通用寄存器之间设置一个高速的、容量相对较小的存储器,把正在执行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用,这对提高系统的性能很有帮助。这个位于主存和CPU之间的高速小容量存储器称作高速缓冲器(Cache)。
启用Cache之后,CPU读取数据时,如果Cache中有这个数据的副本则直接返回,否则从主存中读入数据,并存入Cache中,下次读取这个数据时,可以直接使用Cache中的副本。
2.Write Through模式与Write Back模式
启用Cache之后,CPU写数据时有Write Through和Write Back两种方式。
(1)Write Through模式
任一从CPU发出的写信号送到Cache的同时,也写入主存,以保证主存的数据能够同步的更新。这种方法的特点是操作简单,但由于主存速度相对较低,所以降低了系统的写速度并且占用了较多的总线时间。
(2)Write Back模式
数据一般只写到Cache,这样有可能出现Cache中数据得到更新而主存中的数据不变的情况,当Cache中的数据被换出或者强制进行"清空"操作时,才将更新的数据写入主存相应的单元中。
3.Cache的两个操作
(1)"清空":把Cache或Write buffer中已经更新过的数据写入主存。
(2)"使无效":是之不能再使用,并不将更新过的数据写入主存。
4.2440内置的指令Cache、数据Cache和写缓存(Write buffer)
(1)指令Cache(ICaches)
ICaches的使用比较简单,系统刚上电或复位时,ICaches中的内容是无效的,并且ICaches功能是关闭的。往Icr(CP15协处理器寄存器1中的第12位)写1可以启动ICaches,写0可以停止使用ICaches。
ICaches一般在MMU开启之后被使用,此时页表描述符中的C位(Ctt)用来表示一段内存是否可以被Cache。但是即使MMU没有开启,ICaches也是可以被使用的,这时CPU读取指令时所涉及的内存都被当做是允许Cache的。ICaches被关闭时,CPU每次读取指令都要读取主存,性能非常低,所以应尽早启动ICaches。
ICaches被开启后,CPU每次读取指令时都会先在ICaches中查看是否能够找到所需要的指令,而不管Ctt是0或1。ICaches开启后,CPU的读取指令分为如下3种情况:
A.Cache命中且Ctt为1(Ctt=1表示允许被Cache),从ICaches中读取指令,返回CPU。
B.Cache缺失且Ctt为1,CPU从主存中读取指令。同时会将指令所在区域的8个word写入某个ICaches条目中,替换算法使用Pseudo-random或round-robin算法,具体可以用CP15中的寄存器1的1位来确定使用哪种替换算法。
C.Ctt为0时,CPU从主存读取指令。
(2)数据Cache(DCaches)
系统上电或复位时默认DCaches是关闭的,Write buffer中的内容也是无效的。往Ccr位(CP15协处理器寄存器1的12位)写1可以启动DCaches,写0关闭DCaches。Write buffer与DCaches紧密结合,没有专门的控制位来开启或停止它。
DCaches必须在MMU开启会后才能使用,因为开启MMU之后才能使用页表中的描述符来定义一块内存如何使用DCaches和Write buffer。
DCaches被关闭后,CPU每次读写数据都要操作主存,DCaches和Write buffer被完全忽略。DCaches开启后,CPU每次读写数据都会先在DCaches中查看是否能找到所需要的数据,而不管Ctt是0还是1。
5.Cache和主存的映射
Cache和主存之间的映射方法大致为三种:全相联映射、直接相联映射和组相联映射。Cache和主存都被划分为同样大小的块,以下假设主存被划分为300(1~300)块,Cache被划分为10(1~10)块做说明。
(1)全相联映射
主存中1~300中的任一块的块可以映射到Cache1~10中的任一块,这种方法的特点是简单,但是查找效率低。
(2)直接相联映射
假设主存中1~30块只能映射到Cache的1号块中,依次类推。这样相比全相联查找效率高,根据VA很快可以获取查找结果(命中或缺失)。
(3)组相联映射
直接相联映射在处理抖动时会出现频繁的置换Cache,即主存中1、2、3号内存被交替访问时,将会出现不停的置换Cache中的1号块。组相联结合全相联和直接相联的特点,将Cache分为大块(大块使用直接相联),小块使用全相联,可以有效的避免抖动访问带来的影响。
6.2440的MMU、TLB及Cache控制指令
2440的协处理器也是一个微处理器,用来帮助主CPU完成一些特殊功能,比如浮点计算等。对于MMU、TLB和Cache的操作就涉及到协处理器。CPU核和协处理器之间传送数据时使用这两条指令:MRC和MCR,它们的格式如下:
<MCR|MRC> {cond} p#,<expression1>,Rd,cn,cm{,<expression2>}
MCR:从协处理器获得数据传递给CPU核
MRC:从CPU核获取数据传递给协处理器
{cond}:执行条件,省略时表示无条件执行
p#:协处理器序号
<expression1>:常数1
Rd:CPU核寄存器
cn和cm:协处理器中的寄存器
<expression2>:常数2
7.Cache操作注意点
与TLB类似,使用Cache时需要保证Cache、Write buffer的内容和主存的内容保持一致,需要遵循以下两个原则:
(1)清空DCaches,使得主存数据得到更新。
(2)清空ICaches,使得CPU读取指令时重新读取主存。
在实际编写程序时,要注意以下几点:
(1)开启MMU前,使无效ICaches、DCaches和Write buffer。
(2)关闭MMU前,清空ICaches、DCaches,即将更新过的数据写入主存。
(3)如果代码右边,使无效ICaches,这样CPU取指令时会重新读取主存。
(4)使用DMA操作可以被Cache的内存时:将内存的数据发送出去时,要清空Cache;将内存的数据读入时,要使无效Cache。
(5)改变页表中地址映射关系时也要慎重考虑。
(6)开启ICahces或者DCaches时,要考虑ICahces或者DCaches中的内容与主存是否一致。
(7)对于I/O地址空间,不使用Cache和Write buffer。所谓I/O地址空间,就是对于其中的连续两次的写操作不能合并在一起,每次读/写都必须是直接访问设备,否则程序的运行结果无法预料。