LRU cache原理C++實現

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章