

高速缓冲存储器
内存一般采用SDRAM芯片,对内存的访问肯定是不及CPU的速度的,通常说内存访问要比CPU的速度慢的多。也就是说内存拖后腿了。
CPU访问内存并不是完全随机的。 在某个时间段内,CPU总是访问当前内存地址的相邻内存地址, 想象一下指令顺序执行和循环执行的情景, 这种情景就是著名的程序局部性原理。
基于程序局部性原理,CPU和内存之间可以放置一个小而快的中间存储器,它的速度和CPU的速度差不多,事实上要慢一丢丢,但比内存快得多,这就是高速缓冲存储器。
高速缓冲存储器可以是统一的也可以是分开的。
统一是指数据和指令放在同一个缓冲器中
分开是指数据和指令分别用不同的缓冲器存放
RAM分两种,一种是静态RAM,SRAM(Static RAM);一种是动态RAM,DRAM(Dynamic RAM)。前者的存储速率要比后者快得多
使用的内存一般都是动态RAM。为了增加系统的速率,把缓存扩大就行了,扩的越大,缓存的数据越多,系统就越快了,缓存通常都是静态RAM,速率是非常的快, 但是静态RAM集成度低(存储相同的数据,静态RAM的体积是动态RAM的6倍), 价格高(同容量的静态RAM是动态RAM的四倍), 由此可见,扩大静态RAM作为缓存是一个非常愚蠢的行为, 但是为了提高系统的性能和速率,必须要扩大缓存, 这样就有了一个折中的方法,不扩大原来的静态RAM缓存,而是增加一些高速动态RAM做为缓存, 这些高速动态RAM速率要比常规动态RAM快,但比原来的静态RAM缓存慢, 把原来的静态RAM缓存叫一级缓存,而把后来增加的动态RAM叫二级缓存。
缓存只是内存中少部分数据的复制品,所以CPU到缓存中寻找数据时,也会出现找不到的情况(因为这些数据没有从内存复制到缓存中去),这时CPU还是会到内存中去找数据,这样系统的速率就慢下来了,不过CPU会把这些数据复制到缓存中去,以便下一次不要再到内存中去取。随着时间的变化,被访问得最频繁的数据不是一成不变的,也就是说,刚才还不频繁的数据,此时已经需要被频繁的访问,刚才还是最频繁的数据,又不频繁了,所以说缓存中的数据要经常按照一定的算法来更换,这样才能保证缓存中的数据是被访问最频繁的。
CPU下一次要读取的数据90%都在CPU缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。

根据Cache的工作机制, 可以把Cache分成很多类型, 我们主要看看下面两种类型, 在ARM920T中知道这两种就够了。 当然了解这两种类型是为了要说明后面要注意的问题, “要注意的问题”才是重要的。
当CPU执行写数据操作时, 回写式Cache只把该数据写入其数据地址对应的Cache块中, 不直接写入内存。
当CPU执行写数据操作时, 写通式Cache必须同时把该数据写入其数据地址对应的Cache块和内存中。
采用Cache后可能出现的问题
如果硬件系统中有多核心的CPU, 每个CPU核心内部都有独立的Cache。 这时如果内存中有个全局数据A且A=0。 如果两个CPU核都对其执行加1操作。 如果按照下面的执行顺序, 就会出现问题。 而事实上如果不加控制我们无法对这种硬件的执行顺序进行估计, 很有可能就发生
下面的执行顺序。
1) CPU0读取内存中A的数据到R0寄存器, 并且缓存A的数据到CPU0的Cache中。 CPU0的R0寄存器中为0, CPU0的Cache中A数据对应的Cache块中的单元为0。2) CPU0对它的R0寄存器执行加1操作, 并且把结果写入CPU0的Cache中, 假定这个Cache是回写式Cache, CPU0的Cache中A数据对应的Cache块中的单元为1。 CPU0接着执行下一条指令。
3) CPU1读取内存中A的数据到R1寄存器, 并且缓存A的数据到CPU1的Cache中。 由于第2) 步中CPU0的Cache中的A数据没有回写到内存中, 内存中A数据没有改变。 所以CPU1的R1寄存器中为0, CPU1的Cache中A数据对应的Cache块中的单元为0。
4) CPU1对它的R1寄存器执行加1操作, 并且把结果写入CPU1的Cache中, 假定这个Cache是回写式Cache, CPU1的Cache中A数据对应的Cache块中的单元为1。 CPU1接着执行下一条指令。这时不管哪个CPU的Cache中A数据对应的Cache块发生了替换, 内存中数据A为1。
在打开Cache的情况下, 如果读取RTC寄存器中的状态数据时, 很有可能读取的不是RTC寄存器的最新数据而是读取缓存在Cache中的数据。 这会使我们获取的数据不准确, 有时会产生致命的错误。 如果写入数据到RTC寄存器中对RTC设备进行控制。 这个数据会首先写入Cache中(如果是回写式Cache) 。 我们满心以为RTC设备已经得到了控制,然而我们错了, 这时控制数据也许还在Cache中, 还没有到RTC设备控制寄存器中去。 当然其他设备也是一样。 这种问题非常危险, 而且这种类型的错误根本就不是由程序代码本身的问题导致的, 查起来也不是一般的困难。
解决方式:
解决上述问题的最好方法是, 对映射设备寄存器的存储器地址空间, 不执行Cache缓存。 在MMU的章节中, 了解到每个页表条目中有C、 B两个位。 这两个位就是控制这个页表条目映射的地址空间, 是否被Cache部件(C位) 或者写缓冲部件(B位, 写缓冲也是一种小型的Cache, 但是不详细研究它) 缓存。 只要把设备寄存器所在的页面的页表条目中的C、 B位设置为0, 就解决上述问题了。
上一篇:关于春雨的儿童诗
下一篇:TuckER 论文笔记