DULO:一种利用时间和空间局部性的高效缓存置换策略

一篇值得好好研究的cache buffer置换策略论文,一个星期的时间翻译。

DULO:一种利用时间和空间局部性的高效缓存置换策略

摘要:

磁盘上的被请求的块的Sequentiality,即他们的spatial locality,对于磁盘的效率是非常的关键的,因为磁盘的throughput在访问顺序块时会一阶的高于访问随机块。不幸的是,块的spatial locality被大大的忽略了,只有temporal locality在缓存管理中被考虑。因此,不是以sequential访问为主导的磁盘工作效率会被大大削弱。为了解决这个问题,我们提出一种叫做DULO的策略(Dual Locality),在缓存管理中temporal和spatial locality。平衡了buffer cache的filtering effect后,DULO可以通过使传递到磁盘的请求更sequential,来影响I/O request stream,进而显著提高I/O scheduling和prefetching的效率。

DULO已经通过trace-driven模拟 和在linux2.6.11中的prototype实现被广泛证实。在模拟和系统测量中,各种application的工作量都被测试过,包括WebServer,TPC 基准,和科学程序。我们的实验显示DULO可以显著提高系统throughput,减少程序的运行时间。

1.       说明

硬盘驱动器是最通用的赋存设备,它们支持文件访问和virtual memory。容量增长的符合了急剧增长的数据存储需求,但它的electromechanical (机电)本质导致它的效率改善远远落后于处理器的速度改善。明显的磁盘瓶颈在现在的计算机系统中在恶化,但硬盘作为主流辅存的角色在可以预见的未来是不会改变的,然而application对磁盘数据的请求继续增长。

磁盘的效率被机械操作所限制,包括disk platterrotation(spinning)和disk arm movement(seeking)。Disk head必须通过seeking到达正确的track,通过spinning到达正确的sector,来读写想要的数据。在这两个动作之间,硬盘驱动器的部件影响了效率,disk arm是Achille’sHeel。因为actuator必须通过一系列动作包括acceleration,coast,deceleration,settle精确移动arm到想要的track。因此,访问同一个track上的sequential block与访问几个random block会有一个更大的磁盘throughput.

目前有几种共同打破disk瓶颈的方法。一种是通过memory caching降低磁盘访问。通过使用replacement 算法来利用数据访问的temporal locality,因为被访问的数据在不久的将来会被再次访问,磁盘访问request没有实际上传递到disk就被满足了,为了减小磁盘活动,所有当前的replacement算法都是把减少block miss作为唯一目标。但是这会成为一种误导的准则,可能不能精确地反映怔怔的系统效率。例如,disk seeking被考虑后,请求10个sequential disk block会比请求3个random disk blocks更快。改善真正系统的效率,spatial locality必须被考虑,它可以一阶的改变磁盘效率。但是,在当前的缓存管理中spatial locality 不幸的被忽略了,这篇paper的context中,spatial locality 特指接连不断的requested block的replacement 形成的sequentiality。

另一种打破瓶颈的方法是降低disk arm seeks通过I/O request scheduling。I/O scheduler记录block的requeste queue上的挂起请求 到一个dispatching order,能得到一个最小的seeks和最大的global disk throughput。作为例子的Schedulers包括Shortesst-Seek-Time-First(SSTF),CSCAN,以及 Deadline 和被当前Linux Kernel接受的 anticipatory I/O schedulers.

第三个方法是prefetching。Prefetching manager 通过一个进程打开的文件预测未来的request patterns 。如果一个sequential access pattern 被探测到,那么PM 代表process对当前on-demand的下一个blocks发出requests。因为文件通常顺序放置在磁盘上,所以那么些prefetching request在几次disk seeks后就会被迅速满足。

尽管I/O scheduling 和prefetching可以有效地利用spatial locality并且可以戏剧性的改善那些工作量主要为sequential access的disk throughput,它们处理混杂着sequential和random access的能力,比如web service,database,和科学计算application,是非常有限的。这是因为两种schemes都在一个低于buffer cache的等级上。尽管buffer cache 直接从应用接受I/O requests并且有能力把requests变成需要的I/O requests stream,I/O scheduling和prefetching只能在那些由buffer cache传来的request stream并且recatch在buffer cache management中丢失的opportunity的能力非常有限。因此,在最坏的情况下,一个充满random access的stream阻止I/O scheduling和prefetching来帮忙,因为没有spatial locality可以供他们利用。

联系到失去了利用spatial locality的能力,我们减弱disk瓶颈的方法是一种能利用temporal和spatial locality新的buffer cache management scheme,我们可以叫这种Dual locality scheme DULO。DULO 通过跟踪和利用in-memory pages中的disk placement在操作系统的caching component中引入了dual locality,我们的目标是最大化磁盘提供的I/O request的sequentiality。为了这个目的,我们优先考虑在cache中的random blocks,因为temporal locality与random blocks相当的sequential blocks首先被替换。由于cache在I/O requests上的filtering effects,我们影响application的I/O requests使更多的sequential block request和更少的random block request传递到磁盘。磁盘就可以通过更多的spatial locality来高效的处理request。

2dual locality caching

2.1 一个描述性例子

为了描述当配备了dual locality能力后传统caching scheme的不同,让我们考虑一个混合了sequential和random blocks的reference stream的例子。被访问过的块中,我们假定块A,B,C,和D是散布在不同的track中的随机块。块X1,X2,X3和X4以及块Y1,Y2,Y3和Y4是位于各自tracks上的sequential block。此外,两个各自由由块X1,X2,X3,X4和块Y1,Y2,Y3,Y4组成的不同的文件。假设buffer cache有足够八个block的空间。我们假定应用了LRU replacement 算法和一个类Linux的prefetching 策略。在这个简单的描述中,我们用了average seek time来代表任何一个seek operation的花费,并且使用average rotation time来代表任何一个rotation operation的花费。我们忽略了其他微不足道的花费,比如read和transfer时间。6.5ms的average seek time和3.0ms的average rotation time来自Hitachi Ultrastar 18ZX 10K RPM drive。

Table1显示了reference stream和正在发生的cache states的改变,以及花费在每次传统caching和prefetching策略下的访问与dual locality conscious alternative。在第5次访问中,prefetching被激活并且所有的四个sequential blocks被取到,因为prefetcher知道了reference(to block X1)是从文件头部开始的。两种策略Cache states的不同点是传统的按照严格的LRU order列出了块,然而dual 重新安排了block并且把随机块放到队列的MRUend。所以,当第九次访问引发一个four-block prefetching时,4个random blocks A,B,C和D在traditional中被替换,然而sequential blocks X1,X2,X3和X4在dual中被替换。这两种选择的后果是两个不同的miss streams转变成real disk request。对于traditional来说,来自第17次访问的{A,B,C,D},一个4 random block 磁盘request stream,总时间花费是95.0ms。对于dual,来自第13次访问的{X1,X2,X3,X4},一个four sequential blocks,总的时间花费只有66.5ms。

如果我们不使用prefetching,这两个策略有同样数量的misses。使用prefetching,traditional有10个miss,但是dual只有7个miss,这是因为dual产生了更高质量的I/O request(包括了更多的sequential accesses)来提供更多的prefetching opportunity。

2.2dual locality的挑战

Cache management中引入dual locality带来了traditional所不存在的挑战,并且在上面简单的描述性例子中都很明显。

在当前的cache management中,replacement算法只考虑temporal locality(LRU下队列中的位置)来做出一个替换决定。但是引入了spatial locality后不得不使temporal localit的在替换决定中的权重做出妥协,Temporal locality的角色必须在决定中有作用。Table1中的例子,通过根据weak spatiall locality(weak sequentiality)把他们放到队列的MRU end我们给了random blocks A,B,C,D更多的停留在cache中的权利,尽管他们的有很差的temporal locality(large recency).但是,如果他们几乎没有被再次访问来证明他们有足够的temporal locality,我们肯定不能把他们永远保存到cache中。否则,他们将会用inactive data浪费cache减少cache的效率。同样的考虑也适用于不同size的block sequence。我们偏向于保存一个短的sequence因为仅有少量block来缓冲几乎一个I/O operation的固定耗费。但是,当遇到一个最近没有被访问的short sequence和一个最近访问的long sequence时,我们怎么才能做出一个replacement decision?这个挑战是如何以最大化disk performance为目的在temporal locality(recency)和spatial locality(sequence size)中权衡。

3DULO策略

我们现在把我们的DULO策略同时无缝利用在temporal和spatial locality中。因为LRU或它的变种是最广泛使用的replacement算法,我们使用LRU算法和他的数据结构-LRU stack建立DULO scheme。

在LRU中,刚被取进来的blocks进入stack top,被更换的block从stack bottom离开。在DULO中有两个关键的操作:(1)forming sequence。一个sequence被定义为各自的disk locations临近的blocks并且在一个有限的时间内被访问过。因为一个sequence是从有限大小的stack segment中形成的,并且所有的block根据他们的reference进入stack,定义的第二个条件是自然被满足的。特殊的,random block是一个大小为1的sequence。(2)根据他们的recency(temporal locality)和size(spatial locality)来排列在LRU stack中的顺序,目标是具有large recency和size的sequence放置到LRU stack的stack bottom。因为当新的sequence加入时,sequence的recency在改变,sorted sequence的顺序将会动态的被改变来反映这些变化。

3.1 Structuring LRU stack

为了便利上述的操作,我们把LRU stack分为两个section。Top part被叫做staging section,用来接受新取得的block,bottom part被叫做evicting section,用来存储sorted sequence。我们再次划分stagin section为两个segment。第一个segment被叫做correlation buffer,第二个segment被叫做sequencing bank。DULO中的Correlation buffer类似于LRU-K中的correlation reference period。它的作用是过滤high frequency reference并且组织他们进入sequencing bank,为了减少后来的operational cost。Buffer的大小是固定的。Sequencing bank来作为一个集合来存放blocks to be sequenced,大小从0到最大值BANK_MAX.

假设我们从一个staging section只有correlation buffer(sequencing bank的大小为0)组成的LRU stack开始,并且evicting section保存了stack剩下的部分。当一个block离开evicting section的bottom,一个block进入correlation buffer的top,correlation buffer的bottom block 进入sequencing bank。当有BANK_MAX个block离开evicting section时,sequencing bank的大小是MAX_MAX,我们refill evicting section通过取得bank里的block,从中形成sequences,并且把他们按顺序插入evicting sequences。有三个原因来维持两个interacting section并且使用bank来完成sequences forming:(1)新被接受的block有一个buffering area为形成potential sequences来积累。(2)同时形成的sequences必须共享一个共同的recency,因为组成他们的block是从同一个block pool-staging section中的sequencing bank。通过限制bank大小,我们确定block recency因为spatial locality过分妥协。(3)将要离开stack的block在evicting section中被排序,反映他们的sequentiality和recency来替换。

3.2 Block table:dual的数据结构

为了补充traditional的spatial locality方面不足,我们在OS Kernel里引入了叫做block table的一种数据结构。Block table结构上类似于进程地址转换的multi-level page table。但是有明显的不同在他们之间,因为他们为不同的目的:(1)page table以页为单位包括了进程的virtual address space,page address是table的索引,但block table以block为单位包括了disk space,block locations是table的索引。(2)page table是用来将一个virtual address转换为physical address的,但block table是用来提供对于一个给定block的最近访问次数的。(3)与block table的lookupefficiency相比,page table的lookup efficiency的要求更苛刻,因为page table支持指令执行,而block table应用于I/O operation。那就是为什么一个TLB不得不用来促进page table lookup,但是block table没有这样一个需求。(4)每一个进程有自己的一个page table,每一个disk drive在内存中只有一个block table。

在系统中我们设置一个global variable叫做bank block,每次staging section中的bank被用来forming sequences它就嘀嗒一次。每一个bank中的block把current clock time作为一个timestamp,来代表它最近的访问时间。我们在相应的block disk location在block table的leaf level的entry(BTE,Page Table Entry)记录这个timestamp。BTE结构类似于page table的PTE(Page Table Entry)。每一个BTE允许最多两个最近访问时间记录在里边。当一个新的时间加入,如果BTE满了,最老的时间被替换。另外,为了更高效的管理内存空间,一个timestamp在directory level(相当于linux page table中的PGD(Page Global Directory)和PMD(Page Middle Directory))上在每一个table entry被设置。每次block table在分层查找时记录一个访问时间,时间也在每一个经过的directory entry中被记录为一个timestamp。通过这种方式,当table被当做tree来view时每一个directory entry在那些直接或不直接的children entry维持最新的timestamp。

Block table的内存consumption可以被弹性控制。当系统内存压力大时,系统需要收回table占据的内存,它在一个指定地clock time threshold中遍历table。因为最近访问的时间记录在directory中,一旦找到timestamp小于threshold系统会删除一个directory,并且它之下所有的subdirectory和BTE都会被删除。

3.3Forming sequences

一提到从一个full bank中form sequences,bank clock是一个一个递增的。Bank中的每一个block记录了clock time作为clock table中的一个timestamp。然后,我们遍历table来收集所有的由current block time的block组成的sequences。这是一个低耗费的operation,因为block table中任意level的directory包含了它之下所有BTE的最近的timestamp。这个遍历只进入那些包含了bank中块的directory。为了保证sequences的稳定性,算法决定了具有developing sequence的最后一个块不应该与table中的下一个block合并,如果下一个block属于一下情况之一:

1.       BTE显示当前的clock time它被访问过。这包括了从未被访问过的情况(例如,有一个空的timestamp field)。它属于next block是spare的或者defective block。

2.       current和next两个block中只有一个在current clock time之前没被访问过(例如,只有一个timestamp)。

3.       两个block在current clock time之前都没有被访问过,但他们的last access time有超过一个不同。

4.       current sequence大小达到了允许最大的128,我们认为这足够缓冲一个disk operation耗费。

如果这些条件之一被满足,一个完整的sequence就被form并且一个新的sequence开始被form。否则,next block成为sequence的部分,下面的block连续被test。

3.4 DULO置换算法

DULO置换算法的设计中有两个挑战。

第一个是潜在的巨大开销。在严格的LRU算法中,missed blocks和hit blocks都需要移到stack top。这意味着evicting section中的hit关联了一个bank sequencing cost和一个evicting section中的sequencing ordering cost。这些附加cost会在一个几乎没有memory miss的系统中发生,不能被接受。事实上,严格的LRU算法是几乎不被使用的,因为与每一个memory reference联系过于紧密。它的变种,CLOCK置换算法,在实际上被广泛使用。在CLOCK算法中,当一个blocks命中,只会被标志为一个young block,而不会被移到stack top。当一个block不得不被置换,stack bottom的block会被检查。如果是一个young block,会被移到stack top并且young block 状态删除。否则,这个block被置换。CLOCK很好的模拟了LRU的行为而且它的命中率非常接近于LRU。因为这个原因,我们在CLOCK算法的基础上建立DULO置换算法。也就是它推迟了一个hit block的行动直到它达到stack bottom。通过这种方式,只有block miss可以出发sequencing和evicting section refilling。与miss penalty相比较,这些耗费是非常小的。

第二个是evicting section中的sequences如何根据temporal和spatial locality被order。我们接受了一种应用于Web file caching中近似GreedyDual-Size的算法。GreedyDual-Size最初从GreedyDual中派生出来。通过考虑recency,size还有cached files的fetching cost来做出置换决策。它被证明为在线最优算法,k(cache的size与最小文件的size的比例)-competitive。在我们的案例中,file size等同于sequences size,file fetching cost等同于一个访问sequences的I/O operation cost。对于size变化范围(由bank size限制)很大的sequences,我们假定他们的fetching cost是相等的。我们的算法将来必要时可以改变来适应这种cost变化。

DULO算法为每一个sequence关联一个value H,一个相对较小的数值表示将会被首先evicte。算法有一个global inflation value L,记录了最近被evict的sequence的H value。当一个new sequences加入evicting section,H value被设置为H(s)=L+1/size(s),size(s)是s中block的数目。Evicting section中的sequences和LRUstack bottom中小H value的sequences根据H value排序。算法中一个大size的sequences倾向于stay在stack bottom并且首先被evict。但是,如果一个小size的sequences在相当长时间不被访问就会被replace。因为一个刚被admit的long sequence会由于L value有一个比较大的H value,L value会被evicted block不断地膨胀。当所有的sequences为random blocks(size为1),这个算法退化为LRU算法。

正如我们之前提到的,一旦a bank size of blocks被从evicting section中替换出后,我们用sequencing bank中的blocks来形成sequences并且通过H value来order sequences。注意所有的sequences计算H value时共享同一个L value。新order的sequence list和evicting section中的ordered sequences归并排序,完成evicting section的refilling,staging section仅以那些

Correlation buffer结尾。

4 Performance Evaluation

我们使用trace-driven 模拟和prototype implementation来评价DULO scheme并且展示在应用的不同的access patterns引入spatial locality到置换据侧中的反响。

4.1   DULO simulation

4.1.1Experiment Settings

我们建立一个模拟器来实现DULO scheme,linux prefetching policy,还有Linux Deadline I/O scheduler。我们也实现了Disksim3.0(一个精确地disk simulator),来模拟disk behavior。做的模型是Seagate ST39102LW,10KRPM,9.1GB容量。最大read/write seek time是12.2ms,average rotation time是2.99ms。我们选了五个具有代表性的request patterns的trace来驱动simulator。这里简单介绍这些traces。

Trace viewperf基本上全是由sequential access组成的。Trace通过运行SPEC 2000 benchmark viewperf来采集。在这个trace中,超过99%的reference都是对于几个大文件里的consecutive blocks。相反,trace tpc-h基本上由all-random-access组成。是由支持TPC-decision 的benchmark在MySQL database system上运行时。TPC-H的对于几个大database file的random reference,导致了只有3%的reference在consecutive blocks中。

另外三个是混合的I/O request patterns。Trace glimpse通过使用indexing和query tool“glimpse”在usr目录下text files中搜索text string。Trace multi1通过并行运行cscope,gcc,还有viewperf。Cscope十一哥source code examination tool,gcc是一个GNU compiler。都把Linux Kernel 2.4.20 source code作为他们的input。Cscope和glimpse给出了一个相似的access pattern。他们各自包含了76%和%74%的sequential access。Trace multi2通过并行运行glimpse和tpc-h。multi2的sequential access比multi1少(16%对75%)。

在模拟中,我们设置sequencing bank size为8MB,大多数情况下evicting section size为64MB,只有demanded memory size小于80MB时,设置sequencing bank size为4MB,evicting sequences size为16MB。这些choices基于section 4.1.3中的parameters sensitivity studies的。在这个Evaluation中,我们比较DULO Performance和CLOCK算法。为了普遍适用性,我们仍把它叫做LRU。

4.1.2 Evaluation Results

图3、4显示了LRU和DULO的caching schemes在五个workload下改变memory size时的

execution times,hit ratios,disk access sequences size distributions。因为DULO改善系统效率的effort是来影响对disk的request的质量—sequential block access的数量(sequences size),我们展示出运行在LRU和DULO caching scheme下五种workload的sequences size的不同。因为这个原因,我们使用CDF curves来展示requested block出现在那些size小于一个特定threshold的sequences中的percentage。对于每一个Trace,我们选择两个memory size来画相应的LRU和DULO的CDF curves。我们根据execution time figure中LRU和DULO的execution time gaps选择memory size--一个memory size取决于small gap另一个取决于large gap。Memory size在CDF figure的图例中有。

首先,考察Figure3,CDF curves展示了almost-all-sequential的workload viewperf,超过80%的requested block在size大于120的sequences中。尽管DULO可以增加short sequences的size,因此降低4.4%的execution time,但作用是有限的。对于almost-all-random workload tpc-h,明显DULO不能从由纯random blocks组成的application requests建立sequential disk requests。所以我们看到DULO几乎没有改善。

DULO对于混合requests patterns有大量的效率改善。从图中可以观察出。首先,sequences size的increase跟execution time和hit ratio improvement是直接关联。我们把multi1作为一个例子,80MB的memory size,DULO使16.1%requested blocks出现在size大于40的sequences中,而LRU是13.7%。据此,有8.5%的execution time reduction和3.8%的hit ratio increase。相反,160MB的memory size,DULO使24.9%的requested blocks出现在size大于40的sequences中,而LRU是14.0%。据此,55.3%的execution time reduction和29.5%的hit ratio increase。这个关系明显的表明requested sequences size是一个影响disk Performance的关键因素,并且DULO通过增加sequences size做出了贡献。DULO可以通过对long sequences更有效的prefetching和产生更多hits on prefetched blocks来增加hit ratio。第二,sequential access在DULO中平衡buffer cache的filtering effects时是非常重要的。我们看到DULO在glimpse和multi1中做的比较好。我们知道了glimpse和multi1有74%和75%的sequential access,而multi2中有16%的sequential access。Multi2中的小部分sequential access使DULO防止random blocks被置换的能力降低,因为没有足够的sequentially accessed blocks被置换。第三,multi1在DULO中与glimpse相比有更多的pronounced Performance improvement。这个不同主要因为DULO通过循环access pattern(大家都知道LRU在这方面做得很差)更好的利用temporal locality顺便改善了LRU hit ratios。相比之下,在multi2的情况下,DULO几乎不能改善hit ratio,但是可以客观的降低execution time,明显的表现出在利用spatial locality中的效率。

4.1.3 Parameter Sensitivity和overhead Study

DULO中有两个Parameter,(最大)sequencing bank size和(最小)evicting size。这两个size应该与workload access patterns相关联而不是memory size,因为他们用来manage accessed blocks的sequentiality。我们使用四个workload来研究,派出了viewperf因为memory demand很小。

Table3 表示了execution time在不同sequencing size下的变化。我们观察到不同access patterns的workload中,从4mb到16mb有一个最佳的bank size。原因是太small size的bank几乎没有机会形成long sequences。同时,bank size必须小于evicting section size。当bank size接近section size时,效率将会降低。因为large bank size导致了evicting section被太晚refill而且导致evicting section中的random blocks不得不evicted。所以在我们的实验中,我们选择8mb作为bank size。

Table4 展示了随着不同的evicting section size,execution time的改变。明显的,section size越大,DULO就会对section中的blocks的eviction order有更多的control,经常意味着更好的Performance。图确实显示了这种趋势。与此同时,图也显示了一旦size超过64mb到128mb范围,增大的evicting section发生饱和。我们的试验中,我们选取64mb作为section size因为我们的workload的memory demand相对较小。

DULO的空间开销是它的block table,它的size增长与compulsory miss的数目对应。只有一波compulsory miss可以导致table size迅速增加。但是,table space可以被系统reclaim(section3.2)。DULO的time overhead很琐碎,因为与miss有联系。我们的模拟表现了miss与一个block sequencing operation(把block放入block table并且与最近的block比较,1.7merge sort comparison operation)。

4.2   DULO的implementation

为了展示DULO对于运行在一个modern OS上的效率改善,我们在最新的Linux Kernel 2.6.11上实现了DULO。Real system Evaluation比Trace simulation的一个好处是它可以把所有的memory usage计算在内,包括process memory还有file-mapped memory pages。例如,由于time和space耗费的限制,几乎不可能忠实记录所有的memory page access为一个trace。因此,我们在模拟实验中使用的trace只能通过system calls来反映file access activities。为了展现一个全面综合的DULO Evaluation,我们的Kernel implementation和system measurement有效的补充了我们的trace simulation results。

让我们从一个简单Linux replacement policy-LRU变体的实现开始。

4.2.1          Linux caching

linux使用了一个类似2Q replacement的LRU变体。Linux2.6 kernel把所有的process pages和file pages分为两个叫做active list和inactive list的LRU lists。正如名字暗示的,active list被用来store最近actively被访问的page,inactive list用来store那些有些时间没被access的page。一个faulted-in page经常在inactive list的tail被select。一个inactive page当被作为一个file page访问时进入active list(mark_page_accessed()),或者作为一个process page访问时,它的引用在inactive list tail被检测。一个active page进入inactive list如果它被决定最近不被access(refill_inactive_zone())。

4.2.2          Implementation Issues

在我们的DULO的prototype implementation中,我们不根据忠实的DULO scheme实现replace原始original linux page frame。相反,我们选择保持existing data structure和policies基本不变,无缝的把DULO编入。我们做出这个选择,不得不忍受一些original DULO design的compromise,来服务于一个目的,展示考虑在不改变基本replacement policy的情况下dual locality可以带给一个existing spatial-locality-unaware系统的改善。

在linux中,我们把inactive list分成一个staging section和一个evicting section,因为list中new block被add并且old block被replace。两个LRU list在Linux中使用而不是DULO中假定的一个,这条站了使用一个staging section中的一个bank来form a sequence。我们知道DULO中的sequencing bank是用来连续收集accessed pages并且为他们形成sequences的,所以sequence中的pages可以被同时requested并且被fetch sequentially。在两个list中,刚被访问的page和从active list中demote的最近未访问的page可能被加入到inactive list中并且可能在the same bank中被sequence。因此,两个spatially sequential但是temporally remote的page可能被分如一个sequence,这明显的与section4开头描述的sequence definition有冲突。我们通过mark那些demoted的active page并且独立sequence每一类page来解决这个问题。明显的,跟那些任何hit page对一个有faulted-in pages的possible sequencing是available的  的一个stack case中相比,Linux two-list structure 提供了少的机会使DULO来identify 这些sequences。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章