DULO:一种利用时间和空间局部性的高效缓存置换策略(DULO: An Effective Buffer Cache Management Scheme to Exploit Both Tempora

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

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

摘要:

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

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

1.       说明

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

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

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

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

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

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

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

2dual locality caching

2.1 一个描述性例子

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

Table1显示了reference stream和正在发生的cache states的改变,以及花费在每次传统cachingprefetching策略下的访问与dual locality conscious alternative。在第5次访问中,prefetching被激活并且所有的四个sequential blocks被取到,因为prefetcher知道了referenceto block X1)是从文件头部开始的。两种策略Cache states的不同点是传统的按照严格的LRU order列出了块,然而dual 重新安排了block并且把随机块放到队列的MRUend。所以,当第九次访问引发一个four-block prefetching时,4random blocks A,B,CDtraditional中被替换,然而sequential blocks X1,X2,X3X4dual中被替换。这两种选择的后果是两个不同的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。使用prefetchingtraditional10miss,但是dual只有7miss,这是因为dual产生了更高质量的I/O request(包括了更多的sequential accesses)来提供更多的prefetching opportunity

2.2dual locality的挑战

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

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

3DULO策略

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

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

3.1 Structuring LRU stack

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

假设我们从一个staging section只有correlation buffersequencing bank的大小为0)组成的LRU stack开始,并且evicting section保存了stack剩下的部分。当一个block离开evicting sectionbottom,一个block进入correlation buffertopcorrelation bufferbottom block 进入sequencing bank。当有BANK_MAXblock离开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)将要离开stackblockevicting section中被排序,反映他们的sequentialityrecency来替换。

3.2 Block tabledual的数据结构

为了补充traditionalspatial locality方面不足,我们在OS Kernel里引入了叫做block table的一种数据结构。Block table结构上类似于进程地址转换的multi-level page table。但是有明显的不同在他们之间,因为他们为不同的目的:(1page table以页为单位包括了进程的virtual address spacepage addresstable的索引,但block tableblock为单位包括了disk spaceblock locationstable的索引。(2page table是用来将一个virtual address转换为physical address的,但block table是用来提供对于一个给定block的最近访问次数的。(3)与block tablelookupefficiency相比,page tablelookup 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中的blockcurrent clock time作为一个timestamp,来代表它最近的访问时间。我们在相应的block disk locationblock tableleaf levelentryBTEPage Table Entry)记录这个timestampBTE结构类似于page tablePTEPage Table Entry)。每一个BTE允许最多两个最近访问时间记录在里边。当一个新的时间加入,如果BTE满了,最老的时间被替换。另外,为了更高效的管理内存空间,一个timestampdirectory level(相当于linux page table中的PGDPage Global Directory)和PMDPage Middle Directory))上在每一个table entry被设置。每次block table在分层查找时记录一个访问时间,时间也在每一个经过的directory entry中被记录为一个timestamp。通过这种方式,当table被当做treeview时每一个directory entry在那些直接或不直接的children entry维持最新的timestamp

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

3.3Forming sequences

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

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

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

3.       两个blockcurrent 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 blockshit 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 bottomblock会被检查。如果是一个young block,会被移到stack top并且young block 状态删除。否则,这个block被置换。CLOCK很好的模拟了LRU的行为而且它的命中率非常接近于LRU。因为这个原因,我们在CLOCK算法的基础上建立DULO置换算法。也就是它推迟了一个hit block的行动直到它达到stack bottom。通过这种方式,只有block miss可以出发sequencingevicting section refilling。与miss penalty相比较,这些耗费是非常小的。

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

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

正如我们之前提到的,一旦a bank size of blocks被从evicting section中替换出后,我们用sequencing bank中的blocks来形成sequences并且通过H valueorder sequences。注意所有的sequences计算H value时共享同一个L value。新ordersequence listevicting section中的ordered sequences归并排序,完成evicting sectionrefillingstaging 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 schemelinux prefetching policy,还有Linux Deadline I/O scheduler。我们也实现了Disksim3.0(一个精确地disk simulator),来模拟disk behavior。做的模型是Seagate ST39102LW10KRPM9.1GB容量。最大read/write seek time12.2msaverage rotation time2.99ms。我们选了五个具有代表性的request patternstrace来驱动simulator。这里简单介绍这些traces

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

另外三个是混合的I/O request patternsTrace glimpse通过使用indexingquery toolglimpse”在usr目录下text files中搜索text stringTrace multi1通过并行运行cscopegcc,还有viewperfCscope十一哥source code examination toolgcc是一个GNU compiler。都把Linux Kernel 2.4.20 source code作为他们的inputCscopeglimpse给出了一个相似的access pattern。他们各自包含了76%%74%sequential accessTrace multi2通过并行运行glimpsetpc-hmulti2sequential accessmulti1少(16%75%)。

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

4.1.2 Evaluation Results

34显示了LRUDULOcaching schemes在五个workload下改变memory size时的

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

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

DULO对于混合requests patterns有大量的效率改善。从图中可以观察出。首先,sequences sizeincreaseexecution timehit ratio improvement是直接关联。我们把multi1作为一个例子,80MBmemory sizeDULO使16.1%requested blocks出现在size大于40sequences中,而LRU13.7%。据此,有8.5%execution time reduction3.8%hit ratio increase。相反,160MBmemory sizeDULO使24.9%requested blocks出现在size大于40sequences中,而LRU14.0%。据此,55.3%execution time reduction29.5%hit ratio increase。这个关系明显的表明requested sequences size是一个影响disk Performance的关键因素,并且DULO通过增加sequences size做出了贡献。DULO可以通过对long sequences更有效的prefetching和产生更多hits on prefetched blocks来增加hit ratio。第二,sequential accessDULO中平衡buffer cachefiltering effects时是非常重要的。我们看到DULOglimpsemulti1中做的比较好。我们知道了glimpsemulti174%75%sequential access,而multi2中有16%sequential accessMulti2中的小部分sequential access使DULO防止random blocks被置换的能力降低,因为没有足够的sequentially accessed blocks被置换。第三,multi1DULO中与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 Sensitivityoverhead Study

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

Table3 表示了execution time在不同sequencing size下的变化。我们观察到不同access patternsworkload中,从4mb16mb有一个最佳的bank size。原因是太small sizebank几乎没有机会形成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 sizeexecution time的改变。明显的,section size越大,DULO就会对section中的blockseviction order有更多的control,经常意味着更好的Performance。图确实显示了这种趋势。与此同时,图也显示了一旦size超过64mb128mb范围,增大的evicting section发生饱和。我们的试验中,我们选取64mb作为section size因为我们的workloadmemory demand相对较小。

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

4.2   DULOimplementation

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

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

4.2.1          Linux caching

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

4.2.2          Implementation Issues

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值