• cache—主存—辅存三级调度模拟


    近日,在体系结构的课程中,老师留了一个上机作业,为cache—主存—辅存三级调度模拟,要求如下:

    实现三级存储体系的模拟调度程序

    描述:CPU在cache访问数据块,若命中给出对应的cache实地址,若不命中在主存中查找,如果找到调入到cache中,若是cache已满使用LRU算法进行替换,采用写回法保持cache与主存的一致性。若是没有命中在辅存中查找,找到之后调入到主存,并更新cache。

    实验要求:

    (1)主存的容量可以更改

    (2)分配给程序的页面数可以更改

    (3)Cache采用组相连映像,cache大小、组数、组内块数均可以更改

    (4)地址流可以采用输入的方式给出

    (5)辅存部分可以不用实现

    (6)要求有图形化的用户界面,上述参数均可以直接输入。

    (7)显示执行程序时数据块以及页面的替换过程

    (8)编程语言:选取自己熟悉的高级语言

    百度了很久,没有找到Cache组相联映像的LRU替换算法,以下只是自己的一点想法与思路,若有不足,欢迎指正。

    程序运行界面如下:

      

     点击确定后:

      

    第0组Cache块中各个块的使用情况为:
    T1时刻 1
    T2时刻 1
    T3时刻 1 4
    T4时刻 4 1
    T5时刻 4 1
    T6时刻 4 1
    T7时刻 1 0
    T8时刻 0 1
    T9时刻 0 1
    T10时刻 1 5
    T11时刻 5 4
    T12时刻 5 4
    T13时刻 5 4
    T14时刻 5 4
    T15时刻 5 4

    第1组Cache块中各个块的使用情况为:
    T2时刻 2
    T3时刻 2
    T4时刻 2
    T5时刻 2 3
    T6时刻 3 7
    T7时刻 3 7
    T8时刻 3 7
    T9时刻 7 2
    T10时刻 7 2
    T11时刻 7 2
    T12时刻 2 6
    T13时刻 2 6
    T14时刻 6 7
    T15时刻 7 2

    下面是Cache类的代码,主要实现Cache的LRU替换算法,使用LinkedHashMap本身自带的特性实现的LRU算法

    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * 模拟Catch块中的LRU替换算法
     * 此处使用java中LinkedHashMap,利用其自身特性,对removeEldestEntry()方法进行重写
     * @author SUIXUE
     *
     */
    public class Cache {
        
        public  int cacheSize = 2;
        
        public Cache(){
            
        }
        
        public Cache(int cacheSize){
            this.cacheSize = cacheSize;
        }
        
        //此处的写法避免了新建类,也无需继承
        Map<Integer, Integer> map = new LinkedHashMap<Integer, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;
    
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
            return size() > cacheSize;
            }
        };
        
        /**
         * 重写toString()方法
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<Integer, Integer> entry : this.map.entrySet()) {
                sb.append(String.format("%s   ", entry.getKey()));
            }
            return sb.toString();
        }
        
        /**
         * 此处的主要目的是在Cache中采用组相联映像时,在输出结果时同时显示当前时间
         * @param addr
         * @return
         */
        public String display(int[] addr){
            StringBuilder sb = new StringBuilder();
            int index =15-addr.length+1;
            for(int i = 0; i < addr.length;i++){
                this.map.put(addr[i], 0);
                sb.append("T").append(index++).append("时刻   ").append(this.toString()+"\n");
            }
            return sb.toString();
        }
    }

    下面是主界面的代码

      1 import java.awt.BorderLayout;
      2 import java.awt.GridLayout;
      3 import java.awt.event.ActionEvent;
      4 import java.awt.event.ActionListener;
      5 import java.util.ArrayList;
      6 
      7 import javax.swing.BorderFactory;
      8 import javax.swing.JButton;
      9 import javax.swing.JFrame;
     10 import javax.swing.JLabel;
     11 import javax.swing.JOptionPane;
     12 import javax.swing.JPanel;
     13 import javax.swing.JScrollPane;
     14 import javax.swing.JTextArea;
     15 import javax.swing.JTextField;
     16 
     17 /**
     18  * MainFrame类: 继承JFrame,同时实现接口ActionListener
     19  * 
     20  * @author SUIXUE
     21  * 
     22  */
     23 public class MainFrame extends JFrame implements ActionListener {
     24 
     25     /**
     26      * 
     27      */
     28     private static final long serialVersionUID = 1L;
     29 
     30     private int memory = 0;
     31     private int page = 0;
     32     private int memoryQuNum = 0;
     33 
     34     public int cacheSizeNum = 16;
     35     public int cacheGroupNum = 2;
     36     public int cacheBlockNumber = 2;
     37 
     38     private int cacheNum = cacheGroupNum * cacheBlockNumber;
     39     private int memoryBlockNum = 0;
     40     public int[] addr = new int[] {1,2,4,1,3,7,0,1,2,5,4,6,4,7,2};//默认的地址流,可以在界面文本框中更改
     41 
     42     public Cache[] cache;// 将cache的每组看做一个cache块
     43     public ArrayList<Integer>[] cacheAddrs;// 每组都有对应的地址流
     44 
     45     /**
     46      * 初始化Cache分组(本方法是将每个分组看做一个单独独立的Cache块)
     47      */
     48     public void initCache() {
     49         for (int i = 0; i < cache.length; i++) {
     50             cache[i] = new Cache(cacheBlockNumber);
     51         }
     52     }
     53 
     54     /**
     55      * 初始化地址流
     56      * 将用户输入的地址流,通过分析,分别对应进入不同的Cache分组中
     57      */
     58     public void initAddrs() {
     59         for (int i = 0; i < cacheAddrs.length; i++) {
     60             cacheAddrs[i] = new ArrayList<>();
     61         }
     62         for (int i = 0; i < addr.length; i++) {
     63             int temp = addr[i] % this.cacheNum;// 7%4 = 3
     64             int groupNum = temp / this.cacheBlockNumber;// 3/2 = 1
     65             
     66             ArrayList<Integer> arrayList = cacheAddrs[groupNum];
     67             arrayList.add(addr[i]);// 向各组添加地址流
     68             
     69             //当当前地址不对其他组进行影响时,其他组中的Cache地址流其实等同于该时刻仍是它上一次的地址
     70             if(i != 0){
     71                 for(int j = 0; j < cacheGroupNum;j++){
     72                     if(j != groupNum && cacheAddrs[j].size()>0){
     73                         cacheAddrs[j].add(cacheAddrs[j].get(cacheAddrs[j].size()-1));
     74                     }
     75                 }
     76             }
     77         }
     78     }
     79 
     80     private JPanel mainPanel;
     81 
     82     /**
     83      * 左侧面板
     84      */
     85     private JPanel originalPanel;
     86 
     87     // 主存大小
     88     private JPanel memoryPanel;
     89     private JLabel memorySizeLabel;
     90     private JTextField memorySize;
     91 
     92     // 页面数
     93     private JPanel pagePanel;
     94     private JLabel pageNumLabel;
     95     private JTextField pageNum;
     96 
     97     // cache
     98     private JPanel cachePanel;
     99 
    100     // cache大小
    101     private JPanel cacheSizePanel;
    102     private JLabel cacheSizeLabel;
    103     private JTextField cacheSize;
    104 
    105     // 组数
    106     private JPanel cacheGroupSizePanel;
    107     private JLabel cacheGroupSizeLabel;
    108     private JTextField cacheGroupSize;
    109 
    110     // 组内块数
    111     private JPanel cacheBlockNumPanel;
    112     private JLabel cacheBlockNumLabel;
    113     private JTextField cacheBlockNum;
    114 
    115     // 按钮
    116     private JPanel button;
    117     private JPanel addrPanel;
    118     private JTextField addrText;
    119     private JLabel addrLabel;
    120     private JButton affirm;
    121 
    122     /**
    123      * 右侧面板
    124      */
    125     private JScrollPane scrollPanel;
    126     private JPanel resultPanel;
    127 
    128     private JLabel display;
    129 
    130     // 右侧转换结果显示框
    131     private JTextArea resultArea;
    132 
    133     /**
    134      * 构造函数
    135      */
    136     public MainFrame() {
    137         initComponent();
    138     }
    139 
    140     // 初始各组件
    141     private void initComponent() {
    142 
    143         // 设置布局
    144         mainPanel = new JPanel();
    145         mainPanel.setLayout(new GridLayout(1, 2));
    146 
    147         // --------左侧面板---------------
    148         originalPanel = new JPanel();
    149         originalPanel.setLayout(new BorderLayout());
    150 
    151         // -------主存面板----------------
    152         memoryPanel = new JPanel();
    153         memorySizeLabel = new JLabel("主存容量");
    154         memorySize = new JTextField(10);
    155         memorySize.setHorizontalAlignment(JTextField.RIGHT);
    156         memorySize.setText("32");
    157         JLabel unitLabel = new JLabel("KB");
    158         memoryPanel.add(memorySizeLabel, BorderLayout.WEST);
    159         memoryPanel.add(memorySize, BorderLayout.CENTER);
    160         memoryPanel.add(unitLabel, BorderLayout.EAST);
    161 
    162         // ---------页面大小面板----------------
    163         pagePanel = new JPanel();
    164         pageNumLabel = new JLabel("页面大小");
    165         pageNum = new JTextField(10);
    166         pageNum.setHorizontalAlignment(JTextField.RIGHT);
    167         pageNum.setText("3");
    168         JLabel unitLabel1 = new JLabel("页");
    169         pagePanel.add(pageNumLabel, BorderLayout.WEST);
    170         pagePanel.add(pageNum, BorderLayout.CENTER);
    171         pagePanel.add(unitLabel1, BorderLayout.EAST);
    172 
    173         JPanel tempPanel = new JPanel();
    174         tempPanel.setLayout(new GridLayout(2, 1));
    175         tempPanel.add(memoryPanel);
    176         tempPanel.add(pagePanel);
    177 
    178         // -----------cache面板---------------
    179         cachePanel = new JPanel();
    180         cachePanel.setLayout(new GridLayout(3, 1));
    181         cachePanel.setBorder(BorderFactory.createTitledBorder("cache"));
    182 
    183         cacheSizeLabel = new JLabel("cahce大小");
    184         cacheSize = new JTextField(10);
    185         cacheSize.setHorizontalAlignment(JTextField.RIGHT);
    186         cacheSize.setText("16");
    187         JLabel unitLabel2 = new JLabel("KB");
    188         cacheSizePanel = new JPanel();
    189         cacheSizePanel.add(cacheSizeLabel, BorderLayout.WEST);
    190         cacheSizePanel.add(cacheSize, BorderLayout.CENTER);
    191         cacheSizePanel.add(unitLabel2, BorderLayout.EAST);
    192 
    193         cacheGroupSizeLabel = new JLabel("cahce组数");
    194         cacheGroupSize = new JTextField(10);
    195         cacheGroupSize.setHorizontalAlignment(JTextField.RIGHT);
    196         cacheGroupSize.setText("2");
    197         JLabel unitLabel3 = new JLabel("组");
    198         cacheGroupSizePanel = new JPanel();
    199         cacheGroupSizePanel.add(cacheGroupSizeLabel, BorderLayout.WEST);
    200         cacheGroupSizePanel.add(cacheGroupSize, BorderLayout.CENTER);
    201         cacheGroupSizePanel.add(unitLabel3, BorderLayout.EAST);
    202 
    203         cacheBlockNumLabel = new JLabel("组内块数   ");
    204         cacheBlockNum = new JTextField(10);
    205         cacheBlockNum.setHorizontalAlignment(JTextField.RIGHT);
    206         cacheBlockNum.setText("2");
    207         JLabel unitLabel4 = new JLabel("块");
    208         cacheBlockNumPanel = new JPanel();
    209         cacheBlockNumPanel.add(cacheBlockNumLabel, BorderLayout.WEST);
    210         cacheBlockNumPanel.add(cacheBlockNum, BorderLayout.CENTER);
    211         cacheBlockNumPanel.add(unitLabel4, BorderLayout.EAST);
    212 
    213         cachePanel.add(cacheSizePanel);
    214         cachePanel.add(cacheGroupSizePanel);
    215         cachePanel.add(cacheBlockNumPanel);
    216 
    217         button = new JPanel();
    218         button.setLayout(new GridLayout(2,1));
    219         
    220         addrLabel = new JLabel("块地址流   ");
    221         addrText = new JTextField(20);
    222         addrText.setHorizontalAlignment(JTextField.RIGHT);
    223         addrText.setText("1 2 4 1 3 7 0 1 2 5 4 6 4 7 2");
    224         addrPanel = new JPanel();
    225         addrPanel.add(addrLabel,BorderLayout.WEST);
    226         addrPanel.add(addrText,BorderLayout.CENTER);
    227         
    228         JPanel affirmPanel = new JPanel();
    229         affirm = new JButton("确定");
    230         affirmPanel.add(affirm,BorderLayout.CENTER);
    231         
    232         button.add(addrPanel);
    233         button.add(affirmPanel);
    234         affirm.addActionListener(this);
    235 
    236         originalPanel.add(tempPanel, BorderLayout.NORTH);
    237         originalPanel.add(cachePanel, BorderLayout.CENTER);
    238         originalPanel.add(button, BorderLayout.SOUTH);
    239 
    240         // --------右侧面板---------------
    241         resultPanel = new JPanel();
    242         resultPanel.setLayout(new BorderLayout());
    243 
    244         display = new JLabel("Cache中各个块的使用情况");
    245 
    246         resultArea = new JTextArea();
    247         resultArea.setEditable(false);
    248         resultArea.setBorder(BorderFactory.createTitledBorder("RESULT"));
    249 
    250         scrollPanel = new JScrollPane(resultArea);
    251 
    252         resultPanel.add(display, BorderLayout.NORTH);
    253         resultPanel.add(scrollPanel, BorderLayout.CENTER);
    254 
    255         // -------------------------------------------------------
    256         mainPanel.add(originalPanel);
    257         mainPanel.add(resultPanel);
    258         mainPanel.setBorder(BorderFactory.createTitledBorder("三级调度模拟"));
    259 
    260         this.add(mainPanel);
    261         this.setTitle("小可爱的三级调度模拟");
    262         this.setSize(750, 350);
    263         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    264         this.setResizable(false);
    265         this.setLocationRelativeTo(null);
    266         this.setVisible(true);
    267 
    268     }
    269 
    270     @Override
    271     public void actionPerformed(ActionEvent e) {
    272 
    273         try {
    274             this.memory = Integer.valueOf(memorySize.getText());
    275             this.page = Integer.valueOf(pageNum.getText());
    276             this.cacheSizeNum = Integer.valueOf(cacheSize.getText());
    277             this.cacheGroupNum = Integer.valueOf(cacheGroupSize.getText());
    278             this.cacheBlockNumber = Integer.valueOf(cacheBlockNum.getText());
    279             this.cacheNum = cacheGroupNum * cacheBlockNumber;
    280             this.memoryQuNum = this.memory / this.cacheSizeNum;
    281             this.memoryBlockNum = this.memoryQuNum * this.cacheNum;
    282             
    283             cache = new Cache[cacheGroupNum];
    284             cacheAddrs = new ArrayList[cacheGroupNum];
    285             
    286             String addrString = this.addrText.getText();
    287             String[] addrItems = addrString.split(" ");
    288             
    289             for(int i=0;i<addrItems.length;i++){
    290                 this.addr[i]=Integer.parseInt(addrItems[i]);
    291             }
    292 
    293             this.initCache();
    294             this.initAddrs();
    295 
    296             StringBuilder sb = new StringBuilder();
    297             for (int i = 0; i < this.cache.length; i++) {
    298                 sb.append("第").append(i).append("组Cache块中各个块的使用情况为:\n");
    299                 int[] addrTemp = new int[cacheAddrs[i].size()];
    300                 for (int j = 0; j < this.cacheAddrs[i].size(); j++) {
    301                     addrTemp[j] = ((Integer) this.cacheAddrs[i].get(j))
    302                             .intValue();
    303                 }
    304                 sb.append(this.cache[i].display(addrTemp)).append("\n");
    305             }
    306             resultArea.setText(sb.toString());
    307         } catch (Exception ex) {
    308             JOptionPane.showMessageDialog(null, "所有输入均为正整数!\n地址流输入只能用一个空格隔开", "Sorry",
    309                     JOptionPane.INFORMATION_MESSAGE);
    310             memorySize.setText("32");
    311             pageNum.setText("3");
    312             cacheSize.setText("16");
    313             cacheGroupSize.setText("2");
    314             cacheBlockNum.setText("2");
    315             addrText.setText("1 2 4 1 3 7 0 1 2 5 4 6 4 7 2");
    316         }
    317 
    318     }
    319 
    320     /**
    321      * main 方法
    322      * 
    323      * @param args
    324      */
    325     public static void main(String[] args) {
    326         new MainFrame();
    327     }
    328 }
    MainFrame

    在解决Cache的组相联映像中,我主要采用的方法是将地址流随Cache分组而进行分组,只有特定的主存块才能进入到特定的Cache组中。针对每一组的Cache进行基本的Cache的LRU替换算法(Cache类中)

  • 相关阅读:
    人生苦短_我用Python_javascript_var_function_简单笔记_001
    人生苦短_我用Python_logging日志操作_011
    人生苦短_我用Python_configparser/yaml对配置文件读取/写入操作_010
    人生苦短_我用Python_pymysql库对Mysql数据库操作_009
    人生苦短_我用Python_openpyxl库读取Excel文件数据_008
    人生苦短_我用Python_Try_Exception异常捕捉_007
    命令行下编译打包安卓apk
    构建微服务实验环境
    Docker的安全问题以及一些预防方案
    Go 微服务实践
  • 原文地址:https://www.cnblogs.com/suixue/p/5589538.html
Copyright © 2020-2023  润新知