1 全局页面置换算法
以上页面置换算法都是针对单一的应用程序的页面置换算法, 且有一个前提, 就是给单一应用程序分配的物理页帧数量是一定的. 现实中, 给一个应用程序分配的物理页帧数, 该程序产生的缺页中断也就越少, 而且程序运行过程中, 可能某些阶段对于内存的读写操作很多, 某些阶段很少, 所以给一个应用程序分配固定数量的物理页帧是不合理的. 这样就需要一个全局页面置换算法, 可以动态对某个应用程序的物理页帧数进行调整.
2 工作集模型
前文介绍的各种页面置换算法, 都是基于一个前提, 即程序的局部性原理. 但是此原理是否成立?
- 如果局部性原理不成立, 那么各种页面置换算法就没有什么分别, 也没有什么意义. 例如: 假设进程对逻辑页面的访问顺序是1 2 3 4 5 6 7 8 9 ..., 即单调递增, 那么在物理页面数有限的前提下, 不管采用何种置换算法, 每次的页面访问都必然导致缺页中断.
- 如果局部性原理是成立的, 那么如何来证明它的存在, 如何来对它进行定量地分析? 这就是工作集模型.
2.1 工作集
工作集: 一个进程当前正在使用的逻辑页面集合.
可以用一个二元函数来表示:
- 是当前的执行时刻.
- 称为工作集窗口(working set window), 即一个定长的页面访问的时间窗口. 可以表示在时刻前长度的时间范围, 代表着一段时间.
- = 在当前时刻之前的时间窗口当中的所有页面所组成的集合(随着的变化, 该集合也在不断的变化).
- 指工作集的大小, 即页面数目.
2.2 常驻集
常驻集: 指在当前时刻, 进程实际驻留在内存当中的页面集合.
- 工作集是进程在运行过程中固有的性质, 而常驻集取决于系统分配给进程的物理页面数目, 以及所采用的页面置换算法.
- 如果一个进程的整个工作集都在内存中, 即常驻集包含工作集, 那么进程将很顺利地运行, 而不会造成太多的缺页中断(知道工作集发生剧烈变动, 从而过渡到另一个状态).
- 当今成常驻集的大小达到某个数目之后, 再给它分配更多的物理页面, 缺页率也不会明显下降.
3 两个全局置换算法:
3.1 工作集页面置换算法
3.1.1 原理
追踪之前个的引用.
- 在之前个内存访问的页引用是工作集, 被称为窗口大小.
- 实现原理: 获取某时刻的时间窗口为的工作集, 如果此时应用程序所占用的物理页不在工作集中, 就把他直接换出去(也就是说根据工作集实时调整常驻集, 保证常驻集是该时刻之前时间段内一直被使用的物理页).
3.1.2 举例
1. 假设有一个应用程序, 操作系统给其分配了五个物理页帧A, B, C, D, E, 该应用程序对于逻辑页的访问序列是e d a c c d b c e c e a d, 时间窗口的长度是4, 如图:
2. 当e d a c逻辑页面访问请求过来之后, 会产生四次中断:
3. 当请求4进来之后, 此时的工作集应为e d a c, c在工作集中, 也就是不会产生中断, 重新确认此时的工作集, 变成了d a c, 也就是e应该被踢出工作集, 其占用的物理页帧也会被释放出来:
4. 当请求5过来之后, 此时工作集是d a c, d在工作集中, 不会产生缺页中断, 重新确定工作集, 还是d a c:
5. 当请求6过来之后, 此时工作集是d a c, b不在工作集中, 会产生缺页中断, 重新确定工作集, 变成了 c d b, a又被踢出工作集, 其占用的物理页帧也被释放了出来:
6. 当请求7过来之后, 此时工作集是c d b, c在工作集中, 不会产生缺页中断, 重新确定工作集, 还是c d b:
7. 当请求8过来之后, 此时工作集是c d b, e不在工作集中, 会产生缺页中断, 重新确定工作集, 为d b c e, 添加了e, 没有需要被踢出工作集的页面:
8. 当请求9过来之后, 此时工作集是d b c e, c在工作集中, 不会产生缺页中断, 重新确定工作集, 为b c e, d需要被踢出工作集:
9. 当请求10过来之后, 此时工作集是b c e, e在工作集中, 不会产生缺页中断, 重新确定工作集, 为c e, b需要被踢出工作集:
10. 当请求11过来之后, 此时工作集是c e, a不在工作集中, 会产生缺页中断, 重新确定工作集, 为c e a, 没有需要被踢出工作集:
11. 当请求12过来之后, 此时工作集是c e a, d不在工作集中, 会产生缺页中断, 重新确定工作集, 为c e a d, 没有需要被踢出工作集:
3.2 缺页率页面置换算法
3.2.1 原理
可变分配策略: 常驻集大小可变. 例如: 某个进程在刚开始运行的时候, 先根据程序大小给它分配一定数目的物理页面, 然后在进程运行过程中, 动态调整常驻集大小.
- 可采用全局页面置换的方式, 当发生一个缺页中断时, 被置换的页面可以是在其它进程中, 各个并发进程竞争地使用物理页面.
- 优缺点: 性能较好, 但增加了系统开销
- 具体实现: 可以使用缺页率算法(PFF, page fault frequency)来动态调整常驻集的大小.
缺页率:
缺页率表示"缺页次数 / 内存访问次数"(比率)或"缺页的平均时间间隔的倒数". 影响缺页率的因素:
- 页面置换算法
- 分配给进程的物理页面数目
- 页面本身的大小
- 程序的编写方法
缺页率算法:
若运行的程序的缺页率过高, 可通过增加工作集来分配更多的物理页面. 若运行的程序的缺页率过低, 则通过减少工作集来较少它的物理页面数. 力图使运行的每个程序的缺页率保持在一个合理的范围内.
3.2.2 算法实现
保持追踪缺失发生概率:
- 当缺失发生时, 从上次页缺失起计算这个时间差并记录这个时间差, 是上次的页缺失的时间.
- 如果发生页缺失之间的时间差是"大"的, 之后减少工作集的时间窗口(也就是里面的): 如果 (是设置的一个阈值), 之后从内存中移除所有在时间内没有被引用的页.
- 如果发生页缺失之间的时间差是"小"的, 之后增加工作集: 如果, 之后增加缺失页到工作集中.
3.2.3 实例
- 如果, 从工作集中移除没有在被引用的页面.
- 如果, 仅增加缺失页到工作集中.
1. 假设有一个应用程序, 操作系统给其分配了五个物理页帧A, B, C, D, E, 该应用程序对于逻辑页的访问序列是e d a c c d b c e c e a d, 时间差阈值为2, 如图:
2. 前四次访问, 都会产生中断, 所以时间差都是1, 比阈值2小, 所有都会把页面添加到工作集中:
3. 访问4和5, 因为c d都在工作集中, 所以不会产生中断:
4. 当访问6过来时, 此时b不在工作集中, 所以会产生中断, 先把b放入工作集并找到物理页面与其映射. 此时距离上次中断的时间差为3, 大于时间差阈值2, 所以就会把上次中断到这次中断之间工作集中未访问的页面踢出工作集(也就是a e被踢出, 其占用的常驻集中的A E也会被释放出来):
5. 当访问7过来时, c在工作集中, 所以不会产生中断:
6. 当访问8过来时, e不在工作集, 会产生中断, 此时中断时间差为2, 不大于时间差阈值2, 所以直接把e添加进工作集:
7. 当访问9, 10过来时, c, e在工作集, 不会产生中断:
8. 当访问11过来时, a不在工作集, 产生中断, 此时距离上次中断时间为3, 大于时间差阈值, 就会把工作集中在两次中断间未被引用的页面清出:
9. 当访问12过来时, d不在工作集, 产生中断, 此时距离上次中断时间为1, 小于时间差阈值, 直接把d加入工作集: