實驗(三) 請求頁式儲存管理
阿新 • • 發佈:2018-12-14
#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; } };