《Operating System:Three Easy Pieces》阅读笔记<十四>—交换(二)(swaping police)

152 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

交换空间(二)—交换策略

上一节我们介绍了swap scape这一基础概念(这一节的基础),操作系统通过swap space扩大内存,保留访问活跃的page,每一次都通过replacement policy来选择哪一个page来换出内存。我们只看page与进程的关系的话,某种意义上高速内存可以看作整个memory space的cache,衡量一个replacement policy好不好的指标可以是AMAT,具体公式如下

其中Tm是访问内存的开销,Td是访问硬盘的开销,Pm是cache miss的概率,通过公式量化可以算出,由于内存和硬盘速度上的差异,进程访问内存的开销会随cache miss次数呈现巨大差异,举例来说,一个命中率为90%的系统可能比一个命中率为99%的系统内存访问速度慢100倍。事实上在高速硬盘出现前,内存和硬盘的差距实在是太大了,页面替换算法的重要性并没有那么高,因为频繁替换的成本太高,但是现在有SSD,所以替换算法的重要性也陡然增加。

遵循着由易到难的设计思路,replacement policy可以分为FIFO和Random、LRU以及LRU的变体。

在进程未来所有的内存访问我们都已知的情况下,我们可以让每一次replacement去除掉最久以后才访问的page,这是最优的情况。但是很明显这是不可能的,我们只能尝试去接近这个目标,FIFO和Random是简单的初步尝试,从名字就可知道,FIFO像队列一样处理page的替换顺序,先入的页在替换时也先出,Random则是随机选择替换page,模拟如下图所示

FIFO实现简单,但是性能很差,Random同样实现简单,并且性能不稳定,但是在边界情况下也能发挥出性能。

边界情况简单来讲就是各种不符合常理的内存访问,很多replacement策略设计无法考虑到所有的边界情况,而random方法由于自身随机性能够自动处理这种情况,之后我们看到的random方法也都具有这种性质。

在计算机设计中有locality的概念,即某一个对象在被触发后,具有spatial locality和temporal locality的feature,假如P被访问,则P+1和P-1更有可能被访问,并且接下来P更有可能被再次访问。利用这种locality,Least-Recently-Used(LRU)方法被提出,它的基本思想就是,设当前page被访问的时间为T,那么里现在最久没被访问的page则最没有可能被访问,优先换出最远的page。

如何实现LRU,一种实现方法是假设page table或者物理空间中存储page中上一次被访问的时间,在出现需要换出page的时候搜索所有page中访问时间最远的那个page。

然而,对所有page进行搜索,尤其是现代系统page动辄上百万的数量,是极其耗费时间的。因此,近似LRU被提出了,加入了两个概念:use bitclock。通过硬件支持,当进程每一次进行内存访问时,硬件将访问的page所属的use bit设为1,当需要换出page时,操作系统从clock hand指向的page开始遍历(或者其它任何方式,随机也可以),遇到1,则置为0,遇到0,则确认这一个就是要换出的page,这样近似的认为距离上一次访问最久的page就是可以换出的。

基础的policies大概的思想就是这些,以下是它们的性能对比图,越接近黄线的最优越好,左上角的是当内存访问没有locality的一种边界情况,右下角的是一种只有Random有效的边界情况(其它的方法都失效了)

还有一些swap的优化方法,之前介绍page table中有一种dirty bit位,用于标记page是否进行了IO,如果没有进行IO,说明其数据相较于disk没有改动,如果要换出的话可以直接覆盖,如果进行了IO,那么就要将其写回disk中。有的policy对于没有进行IO的page更优先swap。还有page selection策略用于判断操作系统何时进行page swap,还有clustering and grouping策略用于增加swap的效率,这些policies没有replacement那么重要但是在现代操作系统中也是普遍存在的。