#include <cstdio>
#include <iostream>
using namespace std;
typedef struct Node {
int num;
struct Node *next;
}*LinkList, *pNode;
LinkList get_empty_list() {
LinkList head = new Node;
head->next = NULL;
return head;
}
void add_node(LinkList head, pNode new_node) {
new_node->next = head->next;
head->next = new_node;
}
void delete_num(LinkList head, int num) {
pNode p = head, q;
while (p->next) {
if(p->next->num == num) {
q = p->next;
p->next = q->next;
delete(q);
return;
}
else p = p->next;
}
}
void delete_tail(LinkList head) {
pNode p = head;
while (p->next->next != NULL) {
p = p->next;
}
delete(p->next->next);
p->next = NULL;
}
int get_linkList_length(LinkList head) {
int Len = 0; pNode p = head;
while (p->next != NULL) {
Len++;
p = p->next;
}
return Len;
}
void show_list(LinkList head) {
pNode p = head;
while (p->next) {
p = p->next;
cout << p->num << " ";
}
printf("\n");
}
bool check_num(LinkList head, int num) {
pNode p = head;
while (p->next) {
p = p->next;
if (p->num == num) return true;
}
return false;
}
void add_num(LinkList head, int num) {
pNode new_node = new Node;
new_node->num = num;
add_node(head, new_node);
}
#include <cstdio>
#include <cstdlib>
#include <windows.h>
#include <cstring>
#include <vector>
#include <iostream>
#include "linklist.h"
using namespace std;
const int p_num = 5; // 進程的數量
const int page_size = 1000; // 每個頁面的大小爲1k
const int page_num = 128; // 假設有128頁, 指令爲定長指令
struct Page {
int owner; // 表示頁面的所有者
char str[page_size]; // 表示頁面的大小
}page[page_num];
struct Process {
int pid; // 進程程的PID號,用來代替進程名
vector<int> list;
LinkList cache; // 緩存頁
}process[32];
void init(int n) {
// 創建多個進程空間
for (int i=0; i<n; i++) {
process[i].pid = i;
process[i].list.clear();
process[i].cache = get_empty_list();
}
// 分配內存頁給N個進程
for (int i=0; i<page_num; i++) {
page[i].owner = rand() % n + 1; // 這裏0表示內存頁空閒, 比例可調
int pid = page[i].owner - 1;
process[pid].list.push_back(i);
}
cout << "MBT table" << endl;
for (int i=0; i<n; i++) {
cout << "PID: " << i << " ";
cout << "LEN: " << process[i].list.size() << " ";
for (int j=0; j<process[i].list.size(); j++) {
cout << process[i].list[j] << " ";
}
cout << endl;
}
}
vector<int> get_access_list(int page) {
//產生指令序列
vector<int> v; v.clear();
int num = rand() % 512 + 256; // 程序運行執行的指令數量
int pc = 1, flag=0; // pc表示程序計數器, 表示程序的入口
int up = page * 10; // 指令數量不能超過最大範圍
for (int i=0; i<num; i++) {
v.push_back(pc);
if (flag%2 ==0) pc = ++pc % up; // flag=0||2 50%的指令是順序執行的
if (flag == 1) pc = rand() % (pc-1); // flag=1 25%的指令是均勻分佈在前地址部分
if (flag == 3) pc = pc + 1 + (rand() % (up - (pc+1))); // flag=3 25%的指令是均勻分佈在後地址部分
flag = ++flag % 4;
}
return v;
}
void LRU(Process p, vector<int> v, int max_cache_num) {
vector<int> list = p.list;
LinkList cache = p.cache;
while(get_linkList_length(cache) > 0) {
delete_tail(cache);
}
int exist = 0; // cache命中次數
//物理頁 = v[i] / 10, 指令位置 = v[i] % 10
for (int i=0; i<v.size(); i++) {
int flag = check_num(cache, v[i] / 10);
// 如果存在
if (flag) {
exist++;
delete_num(cache, v[i] / 10);
} else {
if (get_linkList_length(cache) >= 5) {
delete_tail(cache);
}
}
add_num(cache, v[i] / 10);
show_list(cache);
}
cout << "total: " << v.size() << " ";
cout << "hit: " << exist << " ";
cout << "loss: " << v.size() - exist << " ";
cout << "accuracy: " << exist / (double)v.size() << endl;
}
int main()
{
init(p_num); // 表示多少個進程
for (int i=0; i<p_num; i++) {
int page = process[i].list.size();
vector<int> v = get_access_list(page);
for (int j=0; j<v.size(); j++) {
printf("%5d", v[j] / 10);
if ((j+1) % 15 == 0) cout << endl;
}
cout << endl;
LRU(process[i], v, 5);
}
return 0;
}