在N-WaysSet-Associative方式的Cache中,CPU如何选用函数f映射Cache中的Set是一个值得讨论的话题。其中最常用的算法是Bit Selection。如图2‑3所示,CPU使用Bits 12~6选择一个合适的Set。此时f(r(i)) = Bits 12~6。
这是一种最快,最简洁的实现方式,使用这种方法带来的最大质疑莫过于Set的选择不够随机。历史上曾经有人试图使用某些pseudo-random算法作为函数f,但是需要明确的是在Set Selection中,严格意义上的Random算法并不可取。
一是因为在SiliconDesign中,很难在较短时间内产生一个随机数,即便使用最常用的LFSR(Linear Feedback ShiftRegister)机制也至少需要一拍的延时,而且也并不是真正随机的。二是因为多数程序具有Spatial Locality特性,依然在有规律地使用Cache,采用严格意义的Random很容易破坏这种规律性。
在许多实现中,SetSelection时选用的pseudo-random算法等效于Hash算法,这些Hash算法多基于XOR-Mapping机制,需要几个XOR门级电路即可实现。诸多研究表明[23][28][29],这种算法在处理Cache Conflict Miss时优于Bit Selection。
在已知的实现中,追求HitTime的L1 Cache很少使用这类Hash机制,但是这些方法依然出现在一些处理器的MLC和LLC设计中,特别是在容量较大的LLC层面。在MLC层面上,多数微架构使用的Set Selection的实现依然是简单而且有效的Bit Selection方式。
BitSelection方式所带来的最大问题是在选择Set时,经常发生碰撞。这种碰撞降低了Cache的整体利用率,这使得系统软件层面在使用物理内存时需要关注这个碰撞,也因此产生了与物理内存分配相关的一系列Index-Aware算法。
操作系统多使用分页机制管理物理内存。使用这种机制时,物理内存被分为若干个4KB[1]大小的页面。当应用程序需要使用内存时,操作系统将从空闲内存池中选用一个未用物理页面(Available Page Frame)。选取未用物理页面的过程因操作系统而异。
有些操作系统在选用这个物理页面时,并没有采用特别的算法,对此无所作为。在很多时候,这种无为而治反而会带来某种随机性,无心插柳柳成荫。对于Cache使用而言,这种无所作为很难带来哪怕是相对的随机。
精心编制的程序与随机性本是水火难容,而且这些程序一直在努力追求着时间局部性和空间局部性,最大化地利用着Cache。这使一系列Index-Aware类的Memory分配算法得以引入。在介绍这些Memory分配算法之前,我们首先介绍采用分页机制后,一个进程如何访问Cache,其示意如图2‑8所示。