虚拟存储器管理之:页面置换算法

时间:2021-07-22 16:42:45

存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。

 

这次的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。

要求如下

1
通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存 容量对命中率的影响。 命中率 
1  页面失效次数 页地址流长度 页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中 的次数。 在本实验中,假定页面大小为 1k,用户虚存容量为 32k,用户内存容 量为 4 页到 32 页。 (2) produce_addstream 通过随机数产生一个指令序列,共 320 条指令。 A、 指令的地址按下述原则生成: 150%的指令是顺序执行的 225%的指令是均匀分布在前地址部分 325%的指令是均匀分布在后地址部分 10 B、 具体的实施方法是: 1) 在[0319]的指令地址之间随机选取一起点 m; 2) 顺序执行一条指令,即执行地址为 m+1 的指令; 3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地 址为 m’; 4) 顺序执行一条指令,地址为 m’+1 的指令 5) 在后地址[m’+2319]中随机选取一条指令并执行; 6) 重复上述步骤 1)~5),直到执行 320 次指令 C、 将指令序列变换称为页地址流 在用户虚存中,按每 k 存放 10 条指令排列虚存地址,即 320 条指令在 虚存中的存放方式为: 第 0 条~第 9 条指令为第 0 页(对应虚存地址为[09]); 第 10 条~第 19 条指令为第 1 页(对应虚存地址为[1019]); 。。。。。。 第 310 条~第 319 条指令为第 31 页(对应虚存地址为[310319]); 按以上方式,用户指令可组成 32 页。 (3)计算并输出下属算法在不同内存容量下的命中率。 1)先进先出的算法(FIFO); 2)最近最少使用算法(LRU); 3)最佳淘汰算法(OPT); 4)最少访问页面算法(LFR);

 

虚拟存储器管理之:页面置换算法

 

 

下面给出Java代码的实现

import java.util.*;


public class A {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Start memory management.\r\n"+"Producing address flow, wait for while, please. ");
        produce_addstream();
        for(int a:stream) {
            System.out.print(a+" ");
        }
        System.out.println("\r\nThere are algorithms in the program \r\n1、 Optimization algorithm\r\n" + 
                "2、 Least recently used algorithm\r\n" + 
                "3、 First in first out algorithm\r\n" + 
                "4、 Least frequently used algorithm Select an algorithm number, please.\r\n");
        int Num = sc.nextInt();
        switch(Num) {
        case 3:
            FIFO(3);
            break;
        case 2:
            LRU(3);
            break;
        case 1:
            OPT(3);
            break;
        case 4:
            LFU(3);
            break;
        default:
            System.out.println("there is not the algorithm in the program");
            break;
        }
        System.out.println("do you try again with anther algorithm(y/n)");
        for(int i=2;i<32;i++) {
            System.out.println("---Msize="+i+"------");
            FIFO(i);
            LRU(i);
            OPT(i);
            LFU(i);
        }
    }
    static List<Integer> stream;
    /**
     * @return 产生指令序列stream
     */
    public static void produce_addstream(){
        stream=new ArrayList<>();
        do {
            int m = (int)((Math.random()*319));//起点
            stream.add(m+1);//执行m+1
            int m2 = (int)((Math.random()*(m+1)));
            stream.add(m2);//执行m2
            stream.add(m2+1);//执行m2+1
            int m3 = (m2+2)+(int)(+Math.random()*(319-m2-2));
            stream.add(m3);//执行[m2+2,319]
        }while(stream.size()<=320);
    }
    /**
     * 根据指令数找到页面
     * @param zhiLing 所需指令
     * @return 指令所在页面
     */
    public static int search(int zhiLing) {
        return zhiLing/10;
    }
    /**
     * 先进先出
     * @param Msize 物理块数
     */
    public static void FIFO(int Msize) {
        Queue<Integer> que = new LinkedList<>();
        Double C = 0.0;//未命中次数
        for(int i=0;i<stream.size();i++) {
            int zhiLing = stream.get(i);
            int yeMian = search(zhiLing);
            if(que.contains(yeMian)) {
                
            }else {
                C++;
                if(que.size()==Msize) {
                    que.poll();
                }
                que.offer(yeMian);
            }
        }
        C-=Msize;
        Double c = 1-(double) (C/320);
        System.out.println("FIFO: "+String.format("%.6f",c)+"   Msize : "+Msize);
    }
    /**
     * 最近最久未使用算法
     * @param Msize 物理块
     */
    public static void LRU(int Msize) {
        Stack<Integer> stack = new Stack<>();
        Double C = 0.0;//未命中次数
        for(int i=0;i<stream.size();i++) {
            int zhiLing = stream.get(i);
            int yeMian = search(zhiLing);
            if(stack.contains(yeMian)) {
                stack.removeElement(yeMian);
                stack.push(yeMian);
            }else {
                C++;
                if(stack.size()==Msize) {
                    stack.removeElement(stack.firstElement());
                }
                stack.push(yeMian);
            }
        }
        C-=Msize;
        Double c = 1-(double) (C/320);
        System.out.println("LRU : "+String.format("%.6f",c)+"   Msize : "+Msize);
    }
    /**
     * 最佳置换算法
     * @param Msize 物理块
     */
    public static void OPT(int Msize) {
        Double C = 0.0;//未命中次数
        Set<Integer> set = new HashSet<>();
        for(int i=0;i<stream.size();i++) {
            int zhiLing = stream.get(i);
            int yeMian = search(zhiLing);
            if(set.contains(yeMian)) {
                
            }else {
                C++;
                if(set.size()==Msize) {
                    int max = -1;//最长时间不会使用的指令的页面
                    int[] temp = new int[32];
                    for(int a:set) {
                        for(int j=i+1;j<stream.size();j++) {
                            if(search(stream.get(j))==a) {
                                temp[a]=j;
                                break;
                            }
                        }
                    }
                    for(int a:set) {
                        if(max==-1) max=a;
                        if(temp[a]==0) {
                            set.remove(a);
                            break;
                        }
                        if(temp[a]>temp[max]) max=a;
                    }
                    if(set.size()==Msize) {
                        set.remove(max);//移除该页面
                    }
                }
                set.add(yeMian);
            }
        }
        C-=Msize;
        Double c = 1-(double) (C/320);
        System.out.println("OPT : "+String.format("%.6f",c)+"   Msize : "+Msize);
    }
    /**
     * 最少使用置换算法
     * @param Msize
     */
    public static void LFU(int Msize) {
        Double C = 0.0;//未命中次数
        Set<Integer> set = new HashSet<>();
        for(int i=0;i<stream.size();i++) {
            int zhiLing = stream.get(i);
            int yeMian = search(zhiLing);
            int[] temp = new int[32];
            if(set.contains(yeMian)) {
                
            }else {
                C++;
                if(set.size()==Msize) {
                    int Min = -1;
                    for(int a:set) {
                        for(int j=i-1;j>=0;j--) {
                            if(search(stream.get(j))==a) {
                                temp[a]=j;
                                break;
                            }
                        }
                    }
                    for(int a:set) {
                        if(Min==-1) {
                            Min=a;
                            continue;
                        }
                        if(temp[a]<temp[Min]) {
                            Min=a;
                        }
                    }
                    set.remove(Min);//移除该页面
                }
                set.add(yeMian);
                temp[yeMian]++;
            }
        }
        C-=Msize;
        Double c = 1-(double) (C/320);
        System.out.println("LFU : "+String.format("%.6f",c)+"   Msize : "+Msize);
    }
}

 

1     通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存

 

容量对命中率的影响。

 

命中率 =1-

页面失效次数

 

页地址流长度

 

 

 

虚拟存储器管理之:页面置换算法

页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中

 

的次数。

 

在本实验中,假定页面大小为 1k,用户虚存容量为 32k,用户内存容

 

量为 4页到 32页。

 

2     produce_addstream 通过随机数产生一个指令序列,共 320 条指令

 

A指令的地址按下述原则生成

 

 

1 50%的指令是顺序执行的

 

225%的指令是均匀分布在前地址部分

 

3 25%的指令是均匀分布在后地址部分

 

10


B、 具体的实施方法是:

 

 

1       [0319]的指令地址之间随机选取一起点 m

 

2       顺序执行一条指令,即执行地址为 m+1的指令;

 

3                                                                                                                  在前地址[0m+1]中随机选取一条指令并执行,该指令的地

 

址为 m’

 

4       顺序执行一条指令,地址为 m’+1的指令

 

5       在后地址[m’+2319]中随机选取一条指令并执行;

 

6       重复上述步骤 1~5),直到执行 320次指令

 

 

C、 将指令序列变换称为页地址流

 

 

在用户虚存中,按每 k存放 10条指令排列虚存地址,即 320条指令在

 

虚存中的存放方式为:

 

0~9条指令为第 0页(对应虚存地址为[09]);

 

10 ~ 19 条指令为第 1 页(对应虚存地址为[1019]);

 

。。。。。。

 

310 ~ 319 条指令为第 31 页(对应虚存地址为[310319]);

 

按以上方式,用户指令可组成 32页。

 

 

3)计算并输出下属算法在不同内存容量下的命中率。

 

 

1)先进先出的算法(FIFO);

 

2)最近最少使用算法(LRU);

 

3)最佳淘汰算法(OPT);

 

4)最少访问页面算法(LFR);