ARM926的Cache和Write buffer

来源:互联网 发布:北海广电网络客服电话 编辑:程序博客网 时间:2024/05/29 04:15

本文有些内容是对网上各种资料的翻译和整理

ARM926的Cache和Write buffer
一、基本概念
Cache是位于CPU和主存储器(SDRAM)之间的高速缓冲存储器(一般使用SRAM),可以加速系统的性能。Cache是按照cache line组织的,当访问主存储器的时候,有可能数据或者指令位于cache line中,我们称之cache hit,这种情况下,不需要访问外部慢速的主存储器,从而加快了存储器的访问速度。也有可能数据或者指令没有位于cache line中,我们称之cache miss,这种情况下,需要从外部的主存储器加载数据或指令到cache中来。由于时间局部性(tmpporal locality)和空间局部性(spatial locality)原理,load 到cache中的数据和指令往往是最近要使用的内容,因此可以提高整体的性能。
Write buffer用于优化写主存储器的性能。当CPU要保存数据的时候,首先写入write buffer,之后write buffer再在适当的时候写入主存储器。通过write buffer,CPU可以全速运行。

二、Cache的组织
Cache按照cache line组织,每个cache line由下面的内容组成:
1、Flag(是否有效)
2、地址高位(一般是地址的若干MSB部分组成)
3、数据块(具体的数据或者指令)
ARM926的cache line是32字节,也就是说cache line中的数据块地址的低5bit都是一样的,因此地址高位就是由地址的[31:5]组成。当CPU访问一个地址的时候,如果该地址的[31:5]bit和cache line中的地址高位匹配并且是有效的cache line,那么cache hit,数据可以直接从cache line的数据库域读取。这样的cache组织很简单,但是效率很低,因为CPU要遍历整个cache以便确定是否cache hit。为了提高效率,cache往往被分成若干个cache set(ARM926EJ的16k的cache被分成128个cache set),因此地址高位又可以进一步细分为:
1、Tag(比对是否cache hit)
2、Set index(选择一个cache set)
引入了cache set之后,cache的操作如下图所示:
 
图片 1 cache操作
首先从若干个cache set中选择一个cache set,之后匹配虚拟地址的tag域,如果匹配则cache hit,否则从main memory获取数据。上图中,L=5 bits(cache line是32B),S=7(128个cache set)。对于16KB的cache而言,经过128个cache set的分配后,一个cache set中有4个cache line(我们称之为four-way set associative cache)。这样检查是否cache hit就变得非常的迅速了。
对于一个cache而言,set-associativity就是cache set中的cache line的数目。对于cpu搜索是否cache hit而言,set-associativity当然是越少越好。不过,如果set-associativity太小,那么当最近经常使用的代码或数据超过了一个cache set的set-associativity的size,cache contention就会发生,因此要不断的从main memory中替换cache line,从而导致性能的下降。

三、Cache的类型
为了保证cache和memory的数据一致性,cache分成三种类型:
1、write through。CPU向cache写入数据时,同时向memory也写一份,使cache和memory的数据保持一致。优点是简单,缺点是每次都要访问memory,速度比较慢。
2、带write buffer的write through。策略同上,只不过不是直接写memory,而是把更新的数据写入到write buffer,在合适的时候才对memory进行更新。
3、write back。CPU更新cache line时,只是把更新的cache line标记为dirty,并不同步更新memory。在cache line要被新进入的数据取代时,才更新 memory。这样做的原因是考虑到很多时候cache存入的是中间结果,没有必要同步更新memory。优点是CPU执行的效率提高,缺点是实现起来技术比较复杂。
在write操作时发生cache miss的时候有两种策略可以选择:
1、简单的写入main memory而没有cache的操作(这称为read allocate cache)
2、分配cache line并将数据从main memory读入。具体写的行为又是和write through或者write back策略相关了(这称为write allocate cache)
根据cache的tag和index使用的是物理地址还是虚拟地址,cache type可以分成:
1、VIVT(Virtual index Virtual tag): 意思是cache的index和tag都是虚拟地址。
2、PIPT(Physical index Physical tag): 意思是cache的index和tag都是物理地址。
3、VIPT(Virtual index Physical tag): 意思是cache的index使用虚拟地址,tag用物理地址。cache 和TLB 可以同时工作, 比不上VIVT 的cache 速度, 但是比PIPT 要好
VIVT的优点是读取cache的时候无须TLB的介入, 速度比较快。不过Virtual index cache的速度是快了,但是会带来其他的问题。例如:一个物理地址的内容可以出现在多个cache line中,这就需要更多的cache flush操作。反而影响了速度。(这就是传说中的cache alias,具体请参考下面的章节)
随着技术进步,TLB查找速度提高了,在cache 用index查找cache的过程中TLB可以完成虚拟地址到物理地址的转换工作,因此在cache比较tag的时候物理地址已经可以使用了,就是说采用physical tag可以和cache并行工作,不会影响cache的速度。因此,在新的ARM构建中(如ARMv6和ARMv7中),采用了VIPT的方式。这种方式仍然有可能造成alias。

四、Cache alias
在linux内核中可能有这样的场景:同一个物理地址被映射到多个不同的虚拟地址上。在这样的场景下,我们可以研究一下cache是如何处理的。
对于PIPT,没有alias,cache中只会有一个cache line的数据,因为cache并不关注虚拟地址,无论如何映射,其物理地址是确定的。
对于VIPT的cache system,在检查cache命中的时候使用physical address tag,而在使用virtual indexes进行cache set查找的时候由于使用不同的虚拟地址而导致多个cache line针对一个物理地址。对于linux的内存管理子系统而言,virtual address space是通过4k的page进行管理的。对于物理地址和虚拟地址,其低12 bit是完全一样。 因此,即使是不同的虚拟地址映射到同一个物理地址,这些虚拟地址的低12bit也是一样的。在这种情况下,如果查找cache set的index位于低12 bit的范围内,那么alais不会发生,因为不同的虚拟地址对应同一个cache line。当index超过低12 bit的范围,就会产生alais。
对于VIVT,cache中总是存在多于一个的cache line 包含这个物理地址的数据。

五、Cache Ambiguity
Cache Ambiguity是指将不同的物理地址映射到相同的虚拟地址而造成的混乱。这种情况下在linux内核中只有在不同进程的用户空间的页面才可能发生。Cache Ambiguity会造成同一个cache line在不同的进程中代表不同的数据, 切换进程的时候需要进行处理。
对于PIPT,不存在Cache Ambiguity,虽然虚拟地址一样,但是物理地址是不同的。
对于VIPT,由于使用物理地址来检查是否cache hit,因此不需要在进程切换的时候flush用户空间的cache来解决Cache Ambiguity的问题。
VIVT会有Cache Ambiguity的问题,一般会在进程切换或者exit mm的时候flush用户空间的cache

六、Memory coherent
Cache在下面几种情况下会有memory coherent的问题:
1、改变地址映射。对于VIVT而言,改变地址映射会导致该虚拟地址对于的cache line的数据已经不对了(物理地址已经改变)。
2、对于哈佛结构的cache(指令cache和数据cache分开),对指令所在地址进行操作会导致一致性问题。
3、DMA相关的操作。
针对上面的描述的场景,通过invalid cache以及clean cache的动作就可以解决一致性的问题,当然,也可以通过将相关的地址映射成nocache的。这里就不具体描述了。



原创粉丝点击