2.2.5 缓存
每个Symbian 电话上使用的CPU都要求有缓存以获得最优性能。缓存的工作是通过持有最近被访问的数据和指令的本地拷贝,把快速的CPU和慢速的内存系统进行隔离。
ARM CPU具有Harvard结构,它有单独的指令和数据端口,相应地就有单独的指令缓存和数据缓存(ICache,DCache)。
缓存借助执行代码重复的本地特征工作。在一个循环里的代码将执行同样的指令,并访问同样的或是类似的数据结构。只要CPU的视图在内存里一致,它不关心数据位于何处——是在RAM里,还是在缓存里。然而,内核不缓存内存映射的外设,因为控制软件对读写外设寄存器有严格的顺序要求。
缓存在cache line里被组织起来,cache line通常包含从一个来自于32字节对齐地址的32个字节数据,以及一个存储这个源地址的标签。一个16KB的缓存将包含512条line。
当CPU请求数据,缓存则确认是否有与请求的地址匹配的line。如果有,请求的数据立即被返回——这个被称为高速缓存命中。如果缓存不包含请求的数据,则产生一个高速缓存未命中。之后,从内存系统将有一个cache line去填充请求的数据,而且随后CPU继续执行。为了确保新cache line的空间,旧cache line将被从缓存里回收。
缓存效率通过它的命中率来衡量——即缓存命中次数与总访问次数的比率。在Symbian OS上,ICache的命中率大约是95%,DCache的命中率是90%。
在高命中率的情况下,CPU能够以接近最快的速度运行,而不用受到内存系统的拖累。这对性能,尤其是对电池寿命来说,都是很美妙的,因为相对于外部内存访问而言,缓存命中只要求很少的电能消耗。
Line填充的操作为内存系统进行了优化,以从内存芯片上吸取顺序发送模式的优点。
一旦MMU被建立起来,缓存也被激活了,它所有的操作将自动执行,而且系统可以更快地运行。EKA2仅需要在缓存必须被擦除时发布缓存控制命令。这可以由以下的某一个原因导致:
● 内存映像在上下文切换时发生了改变
● 新的代码被加载或者现存的代码被丢弃
● 自修改代码的产生
● 从缓存中使用了DMA
2.2.5 .1 虚拟和物理缓存
通过MMU和缓存,CPU被从系统总线隔离开,那么,它们的顺序在Symbian OS上就有了冲突(参见图2.3)。
图2.3 虚拟和物理缓存
当CPU被直接连接到缓存,缓存则使用虚拟地址,并且它依次告诉MMU在系统总线上生成物理地址(图2.3的左部)。
一个物理寻址的缓存将被直接连接到系统总线,而且通过真实的物理地址被索引。从虚拟到物理的查询则在MMU侧发生,这种查询位于CPU和缓存之间(图2.3的右部)。
2.2.5 .1 ARM v5虚拟缓存
在ARM v5和更早期的系统里,MMU位于CPU和缓存之外,这导致了缓存在MMU的虚拟内存域的内部工作。
在这种设计里,所有存储在缓存里的数据都用虚拟地址进行索引,因而当CPU使用虚拟地址请求数据时,不会为了缓存命中而发出MMU翻译的请求。如果缓存未命中,MMU就被唤起以生成物理总线地址。这种设计减少了MMU的工作量并且节省了电能。
虚拟缓存的不利方面是在每次内核在修改页表时必须清空的部分。内核可以通过丢弃的方式使ICache失效,但它必须把DCache里的脏数据清空到内存系统里去。
不幸的是,当执行线程内上下文转换时,Symbian OS移动内存模型要修改虚拟地址映像。这意味着可能要消耗掉很多毫秒的缓存清空是必需的,这就导致了系统性能上的重大损失。在 7.2.1 节,会看到Symbian OS使用独特的被调用固定进程来减小这种缓存清空。
2.2.5 .3 ARM v6物理缓存
ARM结构的第六版引入了全新的MMU,它有新的页表布局、物理缓存、进程应用空间标识符(ASID),并支持2级缓存和IO内存空间。
ARM v6的CPU,比如在1136上,总是在缓存上使用物理地址。这就要求MMU更好地工作以执行每个来自于CPU核心的从虚拟地址到物理地址的查询请求。这项工作通常借助TLB查询。
这种方案的优点在于缓存与物理内存映像是一直同步的,而与虚拟映像的变化无关。该方案还在上下文切换的过程中避免了缓存清空。
为了更好地提升性能,v6 MMU模型引入了应用空间标识符,被称为ASIDs。每个ASID有自己的4KB或8KB PDE,以供地址空间底部的1GB或2GB使用。改变ASID将立刻换出这个地址空间。
就如我将在 7.4.2 节所解释的,EKA2为每个它创建的进程分配了一个ASID,这导致了更快的上下文切换。
2.2.5 .4 指令缓存(ICache)
ICache包含最近被执行的指令,以备它们被复用。ICache里的指令不能被修改,因而可以认为它是只读设备。
当发生缓存未命中,一个line需要被回收的时候,它马上被新的指令重写。这是允许的,虽然它是只读的而且不能修改。在从系统中取下代码的时候,为了保证派生码或自修改码的一致,缓存清空操作是唯一必须的。
为 THUMB指令集编译的代码有一个优势,那就是在ICache上可以适应两倍于ARM的指令。这有助于弥补它在稍慢的性能方面的劣势。
2.2.5 .5 数据缓存(DCache)
当CPU在读数据时,DCache以与ICache一样的方式工作。在缓存里命中的数据被马上返回,而未命中的数据则将从主存上取得,并取代最近被清空line。
数据相关的复杂性被写进了DCache和把它返回给内存的联合策略中。
对于write-through模式的缓存,每次CPU写数据,它都将通过write buffer马上被写出到内存,如果有命中数据则更新缓冲过的拷贝。
write-through缓存保证了内存总是与缓存保持一致。Cache line回收和缓存清空操作不需要往内存回写任何数据,但要允许可以在任何时候丢弃line。
不利方面是系统总线必须支持CPU全速写数据,而且缓存只在读的时候才有效。
Symbian OS为LCD frame buffer使用write-through caching,以保证在显示器上有稳定的像素。因为有了write buffer,写入新像素数据将稍稍获得速度上的提升,而且read–modify–write操作在缓存的作用下将是半自动的。但是,把整个Symbian OS都在write-through cached系统上运行,性能要降低30%以上。
为了在读写时完全利用DCache,Symbian OS使用了一种称为copy-back的方案。命中了的写操作保留在缓存里,在缓存里它们有可能被再次重写。通过在回收的时候才写一次数据,Copy-back大大减少了写操作产生的负担。
被修改的Cache line用dirty bit进行标记,通常两个dirty bit用于一对half line。在回收cache line的时候读取dirty bit的值,被标记了的half line要通过write buffer写回内存。half line用于减少未修改的数据产生写操作,因为未被修改的数据可以被忽略。
清除copy-back缓存上的全部内容需要消耗一些时间,这是因为这些内容可能都已经被修改。
=====================================================================================
说明: 本文由Bequan翻译自Symbian Press的Symbian OS Internals: Real-time Kernal Programming一书。任何人需要转载或引用,请先通过Email(a-pangu@163.com或symbianchn@gmail.com)与Bequan联系,在获得许可后方可转载或引用,否则视为侵权行为。转载或引用时,请在文章中注明上述翻译信息。