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


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

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

    要求如下

    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.
    "+"Producing address flow, wait for while, please. ");
            produce_addstream();
            for(int a:stream) {
                System.out.print(a+" ");
            }
            System.out.println("
    There are algorithms in the program 
    1、 Optimization algorithm
    " + 
                    "2、 Least recently used algorithm
    " + 
                    "3、 First in first out algorithm
    " + 
                    "4、 Least frequently used algorithm Select an algorithm number, please.
    ");
            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);

  • 相关阅读:
    2. Python语言基本语法
    wx.onMenuShareTimeline使用注意事项
    a different object with the same identifier value was already associated with the session:
    linux 下压缩大批量文件
    mysql sleep进程过多,应用级配置
    一次心惊肉跳的服务器误删文件的恢复过程
    分享一个css3写的气泡对话框,适合于即时通讯和留言本的动态内容
    一次Mysql 死锁事故
    adb server is out of date. killing...
    Redis 数据序列化方法 serialize, msgpack, json, hprose 比较
  • 原文地址:https://www.cnblogs.com/godoforange/p/10932426.html
Copyright © 2020-2023  润新知