zoukankan      html  css  js  c++  java
  • 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类中)

  • 相关阅读:
    HDU 3681 Prison Break 越狱(状压DP,变形)
    POJ 2411 Mondriaan's Dream (状压DP,骨牌覆盖,经典)
    ZOJ 3471 Most Powerful (状压DP,经典)
    POJ 2288 Islands and Bridges (状压DP,变形)
    HDU 3001 Travelling (状压DP,3进制)
    POJ 3311 Hie with the Pie (状压DP)
    POJ 1185 炮兵阵地 (状压DP,轮廓线DP)
    FZU 2204 7
    POJ 3254 Corn Fields (状压DP,轮廓线DP)
    ZOJ 3494 BCD Code (数位DP,AC自动机)
  • 原文地址:https://www.cnblogs.com/suixue/p/5589538.html
Copyright © 2011-2022 走看看