页面置换算法!!! FIFO LRU OPT

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
#include <random>
using namespace std;

// 页面置换算法基类
class PageReplacementAlgorithm {
protected:
    int frameCount;         // 物理块数
    vector<int> frames;     // 物理块
    int pageFaults;         // 缺页次数
    int totalReferences;    // 总引用次数

public:
    PageReplacementAlgorithm(int frameCount) 
        : frameCount(frameCount), pageFaults(0), totalReferences(0) {
        frames.resize(frameCount, -1); // -1表示物理块为空
    }

    virtual ~PageReplacementAlgorithm() {}

    // 处理页面访问
    virtual void accessPage(int page) = 0;

    // 获取缺页率
    double getPageFaultRate() const {
        return static_cast<double>(pageFaults) / totalReferences * 100.0;
    }

    // 获取缺页次数
    int getPageFaults() const {
        return pageFaults;
    }

    // 获取总访问序列
    int getTotalReferences() const {
        return totalReferences;
    }

    // 显示当前物理块状态
    void displayFrames() const {
        cout << "物理块状态: ";
        for (int frame : frames) {
            if (frame == -1) {
                cout << "[空] ";
            } else {
                cout << "[" << frame << "] ";
            }
        }
        cout << endl;
    }
};

// FIFO页面置换算法
class FIFO : public PageReplacementAlgorithm {
private:
    int nextReplaceIndex;   // 下一个要替换的页面索引

public:
    FIFO(int frameCount) : PageReplacementAlgorithm(frameCount), nextReplaceIndex(0) {}

    void accessPage(int page) override {
        totalReferences++;
        cout << "访问页面 " << page << ": ";
        
        // 检查页面是否已在内存中
        auto it = find(frames.begin(), frames.end(), page);
        if (it != frames.end()) {
            // 页面已在内存中,不发生缺页
            cout << "命中" << endl;
            displayFrames();
            return;
        }

        // 发生缺页
        pageFaults++;
        cout << "缺页";

        // 如果有空闲物理块
        for (int i = 0; i < frameCount; i++) {
            if (frames[i] == -1) {
                frames[i] = page;
                nextReplaceIndex = (i + 1) % frameCount;
                cout << " - 放入空闲物理块 " << i << endl;
                displayFrames();
                return;
            }
        }

        // 没有空闲物理块,使用FIFO算法替换页面
        int replacedPage = frames[nextReplaceIndex];
        frames[nextReplaceIndex] = page;
        cout << " - 置换页面 " << replacedPage << " (物理块 " << nextReplaceIndex << ")" << endl;
        nextReplaceIndex = (nextReplaceIndex + 1) % frameCount;
        displayFrames();
    }
};

// LRU页面置换算法
class LRU : public PageReplacementAlgorithm {
private:
    vector<int> lastUsed;   // 记录每个页面最后一次使用的时间

public:
    LRU(int frameCount) : PageReplacementAlgorithm(frameCount) {
        lastUsed.resize(frameCount, -1); // -1表示物理块为空
    }

    void accessPage(int page) override {
        totalReferences++;
        cout << "访问页面 " << page << ": ";
        
        // 检查页面是否已在内存中
        auto it = find(frames.begin(), frames.end(), page);
        if (it != frames.end()) {
            // 页面已在内存中,更新最后使用时间
            int index = it - frames.begin();
            lastUsed[index] = totalReferences;
            cout << "命中" << endl;
            displayFrames();
            return;
        }

        // 发生缺页
        pageFaults++;
        cout << "缺页";

        // 如果有空闲物理块
        for (int i = 0; i < frameCount; i++) {
            if (frames[i] == -1) {
                frames[i] = page;
                lastUsed[i] = totalReferences;
                cout << " - 放入空闲物理块 " << i << endl;
                displayFrames();
                return;
            }
        }

        // 没有空闲物理块,使用LRU算法替换页面
        int lruIndex = 0;
        for (int i = 1; i < frameCount; i++) {
            if (lastUsed[i] < lastUsed[lruIndex]) {
                lruIndex = i;
            }
        }

        int replacedPage = frames[lruIndex];
        frames[lruIndex] = page;
        lastUsed[lruIndex] = totalReferences;
        cout << " - 置换页面 " << replacedPage << " (物理块 " << lruIndex << ")" << endl;
        displayFrames();
    }
};

// OPT页面置换算法
class OPT : public PageReplacementAlgorithm {
private:
    const vector<int>& pageSequence;  // 页面访问序列
    int currentPosition;             // 当前在页面访问序列中的位置

public:
    OPT(int frameCount, const vector<int>& pageSequence) 
        : PageReplacementAlgorithm(frameCount), pageSequence(pageSequence), currentPosition(0) {}

    void accessPage(int page) override {
        totalReferences++;
        currentPosition++;
        cout << "访问页面 " << page << ": ";
        
        // 检查页面是否已在内存中
        auto it = find(frames.begin(), frames.end(), page);
        if (it != frames.end()) {
            // 页面已在内存中,不发生缺页
            cout << "命中" << endl;
            displayFrames();
            return;
        }

        // 发生缺页
        pageFaults++;
        cout << "缺页";

        // 如果有空闲物理块
        for (int i = 0; i < frameCount; i++) {
            if (frames[i] == -1) {
                frames[i] = page;
                cout << " - 放入空闲物理块 " << i << endl;
                displayFrames();
                return;
            }
        }

        // 没有空闲物理块,使用OPT算法替换页面
        int replaceIndex = 0;
        int farthest = -1;

        for (int i = 0; i < frameCount; i++) {
            int nextUse = INT_MAX;

            // 查找页面在未来的使用位置
            for (int j = currentPosition; j < pageSequence.size(); j++) {
                if (frames[i] == pageSequence[j]) {
                    nextUse = j;
                    break;
                }
            }

            // 如果某个页面在未来不会被使用,直接替换它
            if (nextUse == INT_MAX) {
                replaceIndex = i;
                break;
            }

            // 找到最远不会被使用的页面
            if (nextUse > farthest) {
                farthest = nextUse;
                replaceIndex = i;
            }
        }

        int replacedPage = frames[replaceIndex];
        frames[replaceIndex] = page;
        cout << " - 置换页面 " << replacedPage << " (物理块 " << replaceIndex << ")";
        if (farthest != INT_MAX) {
            cout << "(未来第 " << farthest - currentPosition + 1 << " 次访问)";
        } else {
            cout << "(未来不再使用)";
        }
        cout << endl;
        displayFrames();
    }
};

// 生成随机页面访问序列
vector<int> generateRandomPageSequence(int length, int maxPageNumber) {
    vector<int> sequence(length);
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, maxPageNumber - 1);

    for (int i = 0; i < length; i++) {
        sequence[i] = dis(gen);
    }

    return sequence;
}

int main() {
    int frameCount;
    cout << "请输入物理块数 (3或4): ";
    cin >> frameCount;

    // 检查输入是否有效
    if (frameCount != 3 && frameCount != 4) {
        cout << "无效的物理块数,必须是3或4。" << endl;
        return 1;
    }

    int choice;
    vector<int> pageSequence;

    cout << "请选择页面访问序列生成方式:" << endl;
    cout << "1. 手动输入" << endl;
    cout << "2. 随机生成" << endl;
    cin >> choice;

    if (choice == 1) {
        int n;
        cout << "请输入页面访问序列的长度: ";
        cin >> n;

        pageSequence.resize(n);
        cout << "请输入页面访问序列(整数,用空格分隔): ";
        for (int i = 0; i < n; i++) {
            cin >> pageSequence[i];
        }
    } else if (choice == 2) {
        int length, maxPageNumber;
        cout << "请输入页面访问序列的长度: ";
        cin >> length;
        cout << "请输入最大页面号: ";
        cin >> maxPageNumber;

        pageSequence = generateRandomPageSequence(length, maxPageNumber);

        cout << "生成的随机页面访问序列: ";
        for (int page : pageSequence) {
            cout << page << " ";
        }
        cout << endl;
    } else {
        cout << "无效的选择" << endl;
        return 1;
    }

    cout << "\n===== 页面置换过程 =====" << endl;
    cout << "页面序列: ";
    for (int page : pageSequence) {
        cout << page << " ";
    }
    cout << endl << endl;

    // 运行FIFO算法
    cout << "===== FIFO算法 =====" << endl;
    FIFO fifo(frameCount);
    for (int page : pageSequence) {
        fifo.accessPage(page);
    }
    cout << "FIFO缺页次数: " << fifo.getPageFaults() << endl;
    cout << "FIFO缺页率: " << fifo.getPageFaultRate() << "%" << endl << endl;

    // 运行LRU算法
    cout << "===== LRU算法 =====" << endl;
    LRU lru(frameCount);
    for (int page : pageSequence) {
        lru.accessPage(page);
    }
    cout << "LRU缺页次数: " << lru.getPageFaults() << endl;
    cout << "LRU缺页率: " << lru.getPageFaultRate() << "%" << endl << endl;

    // 运行OPT算法
    cout << "===== OPT算法 =====" << endl;
    OPT opt(frameCount, pageSequence);
    for (int page : pageSequence) {
        opt.accessPage(page);
    }
    cout << "OPT缺页次数: " << opt.getPageFaults() << endl;
    cout << "OPT缺页率: " << opt.getPageFaultRate() << "%" << endl << endl;

    // 比较算法性能
    cout << "===== 算法性能比较 =====" << endl;
    cout << "FIFO缺页次数: " << fifo.getPageFaults() << endl;
    cout << "LRU缺页次数: " << lru.getPageFaults() << endl;
    cout << "OPT缺页次数: " << opt.getPageFaults() << endl;

    return 0;
}

全部评论

相关推荐

06-06 13:41
门头沟学院 C++
嗨,你好呀!欢迎来到我的频道,在这里记录一下我的第一段实习今天是小厂实习第4天今日感悟:感悟一:出学校之后,遇到问题想请别人帮忙解决最好不要问:啥啥啥怎么办啊?我觉得可以先提出一个方案,然后问别人这个方案是否可行,不行的话别人也会给你提建议也就是说尽量少麻烦别人,尽量少的去耽误别人的时间当然不是说不去麻烦别人,我们刚开始有很多东西不会不了解很正常的感悟二:接这感悟一说,虽然刚开始有很多东西不会不了解很正常的,但是问完一次,最好可以不问第二次,同样的问题问的多了对别人来说也是个麻烦,到时候别人可能也不想帮你了就。所以,在拿到解决方案后,我觉得我们可以给他记下来,也就形成了我们个人的经验。这样,在后续遇到同样的问题的时候,我们也可以迎刃而解!一些碎碎念今天继续测试分配给我的模块,mentor感觉我的进度有点慢了明天要抓点紧,把这个模块给他整完之后还是要想办法申请去干研发,测试学不到什么东西。我入职的实习的岗位也是研发实习生,但是进来就让干测试了。好在也能学到点东西,不过只有刚接触的时候可以,比如前两三个用例。后面的几十个基本就是重复性工作,就索然无味了,对我来说也是一种浪费时间。早上7点起床,洗漱后买了早饭去地铁站跟同校老哥汇合,一起坐地铁去上班。迷迷瞪瞪的好困!到工位,干完杂事,就开始干活了。中午大家一起去吃了饭,还是昨天的那家店,一荤多素,每天还会环环菜,这样感觉也还行,比学校食堂重复的菜好多了,一荤15块午休过后,接着干活到4点的时候,就感觉脑子好累,特别想歇,重复工作干的太多了,无趣晚上6点准时下班,我们几个实习生都是准时走,禁止内卷哈哈!晚上吃了个牛肉面,12块然后就打车回学校了,路上小睡了一觉,眼睛好痛晚上7点到图书馆晚上准备看看论文,马上研二了,小论文需要抓紧了计划学到10点就回宿舍洗漱睡觉今日收支6月工作日天数:20天&nbsp;6月日薪:5000÷20=250元&nbsp;今日消费:早饭4.8,地铁3.6,午饭15,晚饭12,打车12.3,床上用品:三件套:90.9今日总收入:111.4元实习以来总收入:720.6元
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务