1. 程式人生 > >實驗(三) 請求頁式儲存管理

實驗(三) 請求頁式儲存管理

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define SIZE 1<<8     //地址流數上限
#define MAXN 32        //實存地址空間上限
const LL vmsize  = 1<<15;        //虛存容量
const LL page_size = 1<<10;      //頁面大小
const int page_num = 1<<5;       //頁面總數

 //最佳淘汰演算法
class OPT{         
private:
    int table_size;
    const int length = SIZE;        //指令流長度
    int num = page_num;             //頁面總數
    int used;                       //實存中被佔用數
    LL a[SIZE];                     //地址流序列
    int pageno[SIZE];               //頁面序列
    int table[MAXN];                //記憶體-物理塊對映表
    vector<int> pos[page_num];      //pos[j]中記錄頁面j在地址流中以此出現的位置
    int nxt[SIZE][page_num];        //nxt[i][j]表示位置i處,距離頁面j一下次出現的距離
    bool pagefault[page_num];       //頁面失效
    double accuracy;                //命中率
    int page_size;

public:
    void init(){                //初始化
        used = 0;
        table_size = MAXN;
        this->page_size = page_size;
        memset(table,-1,sizeof(table));
        memset(pagefault,1,sizeof(pagefault));
        accuracy = 1.0;
    }
    
    void get_address(){
        for(int i = 0;i < page_num;++i)  pos[i].clear();
        srand(int(time(0)));
        for(int i = 0; i < length;++i){
            a[i] = (LL)rand() % vmsize;
            pageno[i] = a[i] / page_size;
            pos[pageno[i]].push_back(i);
        }
        get_next();
        print_address();
        print_pageno();
    }

    void change_pagesize(int sz){
        if(sz >= (1<<10) && sz <= (1<<13))
            page_size = sz;
    }

    void change_tablesize(int sz){
        if(sz>=1 && sz <= 32)
            table_size = sz;
    }

    void get_next(){        //獲取nxt[i][j]
        int dis;
        for(int j = 0;j < num;++j) {
            int t = pos[j].size();
            int ptr = 0;
            for(int i = 0;i < length; ++i) {
                if(ptr >= t) nxt[i][j] = length + 1;
                else if (i < pos[j][ptr]) nxt[i][j] = pos[j][ptr] - i;
                else{
                    nxt[i][j] = 0;
                    ptr++;
                }
            }
        }
    }

    void run(){                     //排程
        for(int i = 0; i < length;++i){
            bool tag = false;
            int id = pageno[i];
            if(!pagefault[id]) {            //已經在實存內
                continue;          
            }
            accuracy -= (double)1.0/length;              //修改命中率
            pagefault[id] = false;
            if(used < table_size){                     //檢查實存中是否有空閒
                table[used] = id;                //依次新增
                used++;
                continue;   
            }
            //選擇最遠的替換
            int out = -1, dis = -1;
            for(int j = 0,key,d; j < table_size; ++j){
                key = table[j];
                d = nxt[i][key];
                if(d > dis) { 
                    out = j;
                    dis = d;
                }
            }
            pagefault[table[out]] = true;
            table[out] = id;                //替換 
        }
    }

    double get_accuracy(){ return accuracy; }

    void print_address(){
        cout<<"THE VIRTUAL ADDRESS STREAM AS FOLLOWS: "<<endl;
        for(int i = 0;i< length; i+=4){
            for(int j=0;j<4;++j){
                cout<<"a["<<i+j<<"]="<<setw(9)<<setiosflags(ios::left)<<a[i+j];
            }
            cout<<endl;
        }
        cout<<"======================================"<<endl;
    }

    void print_pageno(){
        cout<<"PAGE NUMBER WITH SIZE "<<(page_size>>10)<<"k FOR EACH ADDRESS IS: "<<endl;
        for(int i = 0;i< length; i+=4){
            for(int j=0;j<4;++j){
                cout<<"pageno["<<i+j<<"]: "<<pageno[i+j]<<"\t";
            }
            cout<<endl;
        }
        cout<<"======================================"<<endl;
    }

    void show(){                    //輸出實存中內容
        cout<<"實存中的內容: ";
        for(int i = 0;i < table_size;++i){
            if(table[i]==-1) cout<<"-1\t";
            else cout<<table[i]<<"\t";
        }
        cout<<endl;
    }

    void debug(){           //debug
        for(int i = 0;i < num;++i){
            for(int j = 0;j < length;++j)
                cout<<nxt[j][i]<<" ";
            cout<<endl;
        }      
    }

    ~OPT(){ cout << "End the result for opt "<<endl; }
};