Clock_pro算法描述

来源:互联网 发布:windows优化大师下载 编辑:程序博客网 时间:2024/06/07 00:16
Clock_pro算法描述


一、算法主要思想
  Clock_pro算法与LIRS算法采用相同的原则,它使用页面的再次使用距离,而不是页面的新近访问时间,来决定替换哪个页面。当一个页面被访问时,该页面的再次使用距离是上次访问该页面到本次访问该页面,这一段时间之内,访问过的其他不同页面的数量。虽然,页面的任何两次连续访问都存在一个再次使用距离,但是仅仅只有最近的那个再次使用距离才能决定替换哪个页面。当一个页面被访问时,我们求出其再次使用距离,并根据这个距离将该页面分类,如果该页面的再次使用距离很大,说明它是一个cold页面;如果该页面的再次使用距离很小,说明它是一个hot页面。然后,我们就可以将该页面标记上cold或hot标记。我们将所有被访问的页面,不管是cold还是hot页面,根据它们的访问顺序,将它们放置在单个链表中。在该链表中,具有最小recency值的页面位于链表表头,具有最大recency值的页面位于链表表尾。
  为了给cold页面一个机会变成hot页面,也是为了保证cold/hot状态能够准确地反映当前的访问行为,当一个cold页面进入链表时,我们赋予该cold页面一个检测期。然后,当该cold页面在检测期内被再次访问时,它就将变为hot页面;如果超过检测期,该cold页面没有被再次访问,那么就将该cold页面从链表中删除。注意,该cold页面在检测期内可以被替换出内存,然而,出于检测的目的,该页面的元数据信息仍然保留在链表中直到超过该页面的检测期亦或者是该页面被再次访问。当有必要腾出一个空闲空间时,我们选择一个resident cold页面(在内存中缓存的cold页面,简称为驻存的cold页面)。
  这里,最主要的问题就是怎样设置页面的检测期。当链表中存在一个cold页面,并且至少存在一个hot页面在其后(其后表示该hot页面的recency值大于该cold页面的recency值),那么当该cold页面被再次访问时,它将变为hot页面,因为该cold页面有一个新的再次使用距离,并且小于其后的hot页面。相应的,具有最大recency值的hot页面将变为cold页面(应该还有一个前提:该hot页面的引用位为0)。如果我们确保具有最大recency值的hot页面始终位于链表的尾部,并且所有的cold页面越过处于链表尾的hot页面时将终止它们的检测期,那么一个cold页面的检测期就相当于该cold页面到达链表尾的时间。实际上,我们可以缩短页面的检测期,也可以限制处于检测期中的cold页面数目,以减少空间消耗。
通过实现这种检测机制,我们确保cold/hot状态是通过相对性来定义的,并且是在一个时钟情况下通过常量级比较来实现的,而并不是使用一个固定的阀值来将页面分为cold/hot两个链表。这就使clock_pro算法与先前提出的算法(2Q和CAR)不同,2Q和CAR算法尝试使用一个固定的阀值去区别两种不同类型的页面(cold或hot),并且在不同的页面类型链表中,对待它们的方式也不一样(2Q算法有两个队列,CAR算法有两个时钟),这直接导致2Q和CAR算法拥有LRU算法的性能缺陷。


二、数据结构
我们首先假定分配给hot页面的内存空间为mh,分配给cold页面的内存空间为mc,都是固定的,m=mh+mc为总共的内存空间大小,hot页面的数量也是mh,所以所有的hot页面总是被缓存的。当一个hot页面将被替换时,它将首先转变成cold页面。除了hot页面,其他被访问的页面都被当做cold页面。在cold页面中,有mc个页面是被缓存的,另外最多有m个非驻存的cold页面,仅仅只有它们的历史访问信息被缓存。所以,为了跟踪页面的历史访问信息,最多存在2m个元数据条目在链表中。在CLOCK算法中,所有页条目被组织成一个循环链表,如figure1所示。

对于每一个页面,都有一个cold/hot状态与之关联,对于每一个cold页面,都有一个标记指示其是否处于检测期。
  在clock_pro算法中,有3种指针。HANDhot指向具有最大recency值的hot页面,这个指针指向的位置实际上起一种判断一个cold页面能否成为hot页面的阀值。任何一个被HANDhot指针扫描到的hot页面,如果其引用位不为1的话,该hot页面就会变为cold页面。为了方便描述,我们将HANDhot指向的页面称为链表尾,而以顺时针方向紧随链表尾的页面称为链表头。HANDcold指针指向最后一个驻存的cold页面(此处的最后理解为离链表头最远)。我们总是选择这个位置的cold页面进行替换,所以,这个位置就是我们寻找替换页的起始处,相当于CLOCK算法中那个唯一的指针。HANDtest指针指向处于检测期中的最后一个cold页面,这个指针用于终止cold页面的检测期,被这个指针扫描到的非驻存的cold页面都会从循环链表中删除。这3个指针都以顺时针方向移动。


三、搜寻替换页面的操作
  Clock_pro算法与CLOCK算法一样,当页面命中时没有操作,仅仅只会在硬件层面上将被访问页面的引用位设置一下。在见识一个替换页面是如何产生之前,得先看看那3个指针在链表中是怎么移动的,因为替换页面的搜寻是通过那3个指针的移动协调完成的。
  HANDcold用于查找一个驻存的cold页面来进行替换。
  1、如果HANDcold指向的当前cold页面的引用位为0,我们就将该cold页面替换出去,以腾出一个空闲块。如果该被替换出去的cold页面在其检测期内,那么它将继续以非驻存的cold页面存在于链表中,直到其检测期过期;否则,我们会在链表中将其删除。
  2、然而,如果HANDcold扫描到的cold页面的引用位为1,并且处于其检测期内,就得将该cold页面转变为hot页面,同时,也会请求HANDhot执行一些操作,因为检测期内的一个再次访问,预示着一个有竞争力的小的再次使用距离的产生。
  3、如果HANDcold扫描到的cold页面的引用位为1,但并未处于其检测期内,就不需要有状态的改变,HANDhot也不需要执行其他的操作。
  在2、3的情况下,都会将该页面的引用位重新置0,并且将该页面移至链表头。HANDcold指针将继续移动直到其扫描到一个合适的cold页面进行替换,HANDcold将止步于下一个驻存的cold页面。
  如上面提到的,当一个cold页面在其检测期内被再次访问到时,它将会变成一个hot页面,这也会触发HANDhot指针的移动,因为上述事件有可能会导致具有最大recency值的hot页面转变为cold页面。
  如果HANDhot指向的hot页面的引用位为0,那么我们可以简单地将其状态改为cold,然后向前移动HANDhot指针。
  如果HANDhot指向的hot页面的引用位为1,就表明该hot页面被再一次访问过,此时,我们需要保持该hot页面为hot状态,但是也需要将其引用位清0。然后,移动HANDhot指针,当它扫描到引用位为1的hot页面时,执行上述相同的操作,直到其扫描到一个引用位为0的hot页面,然后将该引用位为0的hot页面转变为cold页面。
  注意,向前移动HANDhot指针,相当于使其扫描过的页面处于链表头。无论何时,当HANDhot指针遇到一个cold页面,它将终止该cold页面的检测期。如果该HANDhot指针遇到一个非驻存的cold页面,会将该页面删除出链表。针对cold页面,HANDhot指针实际上代表HANDtest指针做了一些工作。最终,HANDhot指针终止于一个hot页面。
  我们记录了非驻存的cold页面的数量,一旦那个数目超过了以页数目为单位的内存大小m,我们就终止HANDtest指向的cold页面的检测期,如果该cold页面是非驻存的,我们还将从链表中删除它。因为该cold页面由于没有被再次访问,已经用完了其检测期,在下一次被访问时,它也已经没有机会转变成为hot页面了。HANDtest会继续向前移动,停在下一个cold页面上。
  现在,我们可以总结一下,这3种指针是如何协同工作去解决一个缺页异常。当发生了一个缺页异常之后,所缺的页必然是一个cold页面。我们首先执行HANDcold去寻找一个空闲的块。
  如果所缺的页面不在链表中,那么它的再次使用距离极有可能大于hot页面的recency值,所以该页仍然被归为cold页面,并且被放置于链表头部,另外,还会初始化该页面的检测期。
  如果,cold页面的数量超过了mc+m,我们也会执行HANDtest。
  如果所缺的页面在链表中,那么该所缺的页面将会转变为hot页面,并且被放置于链表头部。然后,还会执行HANDhot去将一个具有较大recency值的hot页面转变为cold页面。


四、使clock_pro算法具有自适应性
  直到现在,我们都是假定分配给hot/cold页面的内存空间是固定的。在LIRS中,的确是有一个预先确定的参数,用Lhirs表示,去衡量用于分配cold页面的内存百分比。Lhirs实际上影响着LIRS的行为与LRU的行为有多大程度的不同,当Lhirs达到100%时,LIRS的替换行为以及命中率都与LRU非常接近。虽然对LIRS算法的性能评估表明,当Lhirs在1%到30%之间变化时,对LIRS算法的性能影响很小,同时它也显示了,对于LRU-friendly型的工作负载,LIRS算法的命中率要比LRU算法的命中率稍低,当增大Lhirs的比率时,可以减小两种算法针对LRU-friendly型的工作负载的性能差距。
  在clock_pro算法中,驻存的cold页面的管理与CLOCK算法中是一样的。HANDcold与CLOCK算法中的clock指针执行的功能相同:扫描pages链表,不动引用位为1的cold页面,将引用位为0的cold页面替换掉。所以,增加分配给cold页面的内存空间mc,使clock_pro算法的行为与CLOCK算法的行为越接近。
  让我们来讨论一下,在clock_pro算法中,改变内存分配空间的大小对其性能的影响。为了克服弱访问模式下(文件扫描和循环),CLOCK算法的性能缺陷,一个小的mc值意味着刚被换进的缺页很快又将被换出,并且可以保证hot页面不受cold页面的影响被轻易的换出。然而,对于强局部性访问流,基本上所有被访问的页面都有比较小的再次使用距离,但是,有些页面不得不被归为cold页面。对于一个小的mc值,一个cold页面被载入进内存后,很快又将不得不被换出内存。由于它的再次使用距离很小,该页又会以缺页的状态进入内存(尽管它刚刚被换出内存),然后,由于其在检测期进行了再次访问,其状态会变为hot。这样,对于那些拥有比较小的再次使用距离的页面,会产生不必要的缺页异常。增大mc的值,将允许这些页面被缓存一个更长的时间,这些页面也就更有可能被访问到,然后转变为hot页面,而不会中途被替换出内存。这样,就可以避免一些不必要的缺页异常。
  对于一个给定再次使用距离的被访问cold页面,mc的值决定了该页面在被替换出内存之前再次被访问的可能性。对于再次使用距离大于其检测期的cold页面,用一个大的mc值将该页面保留在内存中是浪费缓存空间。另一方面,对于一个拥有较小再次使用距离的cold页面,用一个大的mc值使该页面在内存中驻留更长的时间,从而可以减少缺页异常的次数。
在自适应性的clock_pro算法中,我们允许mc的值根据当前再次使用距离的分布动态的调整。
如果一个cold页面在其检测期内被访问,就将mc的值加1;如果一个cold页面在其检测期内没有被再次访问,就将mc的值减1。注意,前面提到的cold页面包括驻存的和非驻存的cold页面。一旦mc的值被改变了,clock_pro的时钟指针将会通过暂时地调整HANDhot和HANDcold的移动速度来实现内存分配。
  有了自适应性,clock_pro算法能够整合LRU算法在面对强局部性工作负载时的优势和LIRS算法在面对弱局部性工作负载时的优势。