设计一个虚拟存储区和内存工作区,并使用下列算法计算访问命中率:(1)进先出的算法(FIFO)(2)最近最少使用的算法(LRU)(3)最佳淘汰算法(OPT)(4)最少访问页面算法(LFU)_设计一个虚拟存储区和内存工作区,并使用下述常用页面置换算法计算访问命中率。 (1-程序员宅基地

技术标签: 算法  python  页面替换算法  Python  

命 中 率 = 1 − 页 面 失 效 次 数 页 地 址 流 长 度 命中率=1-\frac{页面失效次数}{页地址流长度} =1

页面调度算法

  • LRU:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。
  • FIFO:当需要淘汰一个页面时,总是选择驻留主存时间最长的页面进行淘汰,即先进入主存的页面先淘汰。
  • LFU:总是淘汰最近一段时间内使用次数很少的页面。
  • Opt:从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。

代码

总共10页。四个块,程序要30次调用页,的页号序列随机在指定。

# -*- coding: utf-8 -*-

# 运行python3.7.8
import time
import sys
import random
from multiprocessing import *

class Page:
    '''
    页面。
    '''

    def __init__(self, index: int):
        '''
        初始化页面。

        参数
        --------
        index : int
            页序号。
        '''
        self.__index = index
        self.__pv = 0
        self.__last_visit = float(time.time())  # 时间戳
        self.__last_put = -1  # 上次装入时间
        pass

    @property
    def pv(self):
        '''
        访问次数。
        '''
        return self.__pv

    @property
    def last_visit(self):
        '''
        访问时间。
        '''
        return self.__last_visit

    def visit(self):
        self.__pv += 1
        time.sleep(0.001)
        self.__last_visit = float(time.time())  # 时间戳

    @property
    def index(self):
        '''
        页号。
        '''
        return self.__index

    def set_last_put(self):
        self.__last_put = float(time.time())
        pass

    @property
    def last_put(self):
        return self.__last_put

class Mem:
    '''
    为进程申请的独立内存空间。
    '''

    def __init__(self, size: int, func):
        '''
        初始化内存。

        参数
        --------
        size : int
            以页为单位的内存容量。

        func 
            页面置换算法,必需传入名为page、blocks的参数,并返回一个页。
        '''
        self.__blocks = []
        self.__max_size = size
        self.__func = func
        self.__find = 0
        self.__total = 0
        pass

    @property
    def max(self):
        '''
            以页为单位的内存容量。
        '''
        return self.__max_size

    @property
    def size(self):
        '''
        已使用页数。
        '''
        return len(self.__blocks)

    def print_mem(self):
        '''
        打印占页情况。
        '''
        print('[ ', end='')
        first = True
        length = len(self.__blocks)
        for i in range(0, self.__max_size):
            if i < length:
                if first:
                    print(str(self.__blocks[i].index).zfill(2), end='')
                    first = False
                else:
                    print('\t | ' + str(self.__blocks[i].index).zfill(2), end='')
                pass
            else:
                if first:
                    print(' ', end='')
                    first = False
                else:
                    print('\t | '+'-', end='')
                pass
        print('\t]')
        pass

    def get(self, index):
        '''
        查看已经使用的页。
        '''
        if index > 0 and index < self.__size:
            return self.__blocks[index]
        else:
            return None
        pass

    def push(self, page: Page):
        '''
        装入页面。

        参数
        --------
        page : Page
            待装入页面。
        '''
        try:
            for i in self.__blocks:
                if page.index == i.index:
                    i.visit()
                    self.__find += 1
                    self.__total += 1
                    return
            index = None
            if self.size < self.max:
                self.__blocks.append(page)
                self.__total += 1
                page.visit()
                page.set_last_put()
                return
            else:
                rem = self.__func(page=page, blocks=self.__blocks)
                if rem is not None:
                    for i in self.__blocks:
                        if i.index is rem.index:
                            index = self.__blocks.index(i)
                            break
                        pass
            if index is not None:
                self.__blocks[index] = page
                self.__total += 1
                page.visit()
                page.set_last_put()
            pass
        except BaseException as e:
            print(repr(e))
            pass
        else:
            pass
        pass

    @property
    def pfr(self):
        ret = 1-self.hr  # 缺页率
        return ret

    @property
    def hr(self):
        ret = self.__find/self.__total  # 命中率
        return ret

all_pages = []
all_indexs = []
now_index = 0

def run(func, size: int, page_count: int):
    try:
        global all_pages
        global now_index
        all_pages = []
        now_index = 0
        for i in range(0, page_count):
            all_pages.append(Page(i))  # 初始化内存
            pass
        mem = Mem(size, func)
        for index in all_indexs:
            now_index += 1  # 为Opt服务
            print('('+str(now_index).zfill(3)+')\t: ',end='')
            i = all_pages[index]
            mem.push(i)  # 初始化模拟进程
            print(str(i.index).zfill(2), end='\t--> ')
            mem.print_mem()
            pass
        print('-'*16)
        print('Hit rate: ' + str(mem.hr))
        print('Page fault rate: '+str(mem.pfr))
        print('-'*16+'\n')
        pass
    except Exception as e:
        e.print_exc()
        pass
    else:
        pass
    pass

def LRU(page: Page, blocks: list):
    '''
    最久未使用。
    '''
    ret = None
    min = sys.float_info.max
    for i in blocks:
        if i != None:
            if i.last_visit < min:
                ret = i
                min = i.last_visit
    return ret

def FIFO(page: Page, blocks: list):
    '''
    先进先出。
    '''
    ret = None
    min = sys.float_info.max
    for i in blocks:
        if i != None:
            if i.last_put < min:
                ret = i
                min = i.last_put
    return ret

def LFU(page: Page, blocks: list):
    '''
    最少使用。
    '''
    ret = None
    min = sys.maxsize
    for i in blocks:
        if i != None:
            if i.pv < min:
                ret = i
                min = i.pv
    return ret

def Opt(page: Page, blocks: list):
    '''
    最佳。
    '''
    global all_pages
    global now_index
    ret = None
    max = 0
    for i in blocks:
        if i != None:
            d = 0
            for future in range(now_index, len(all_indexs)):
                if all_indexs[future] == i.index:
                    break
                d += 1
                pass
            if d > max:
                ret = i
                max = d
    return ret

def __main__():
    page_count=10
    global all_indexs
    for i in range(0, 30):  # 进程所需页号
        all_indexs.append(random.randint(1, page_count)-1)
        pass
    print('-'*16+'\n'+'LRU:')
    run(LRU, 4, page_count)
    print('-'*16+'\n'+'FIFO:')
    run(FIFO, 4, page_count)
    print('-'*16+'\n'+'LFU:')
    run(LFU, 4, page_count)
    print('-'*16+'\n'+'Opt:')
    run(Opt, 4, page_count)
    pass

__main__()

运行结果

----------------
LRU:
(001)	: 07	--> [ 07	 | -	 | -	 | -	]
(002)	: 05	--> [ 07	 | 05	 | -	 | -	]
(003)	: 03	--> [ 07	 | 05	 | 03	 | -	]
(004)	: 00	--> [ 07	 | 05	 | 03	 | 00	]
(005)	: 06	--> [ 06	 | 05	 | 03	 | 00	]
(006)	: 08	--> [ 06	 | 08	 | 03	 | 00	]
(007)	: 09	--> [ 06	 | 08	 | 09	 | 00	]
(008)	: 01	--> [ 06	 | 08	 | 09	 | 01	]
(009)	: 05	--> [ 05	 | 08	 | 09	 | 01	]
(010)	: 01	--> [ 05	 | 08	 | 09	 | 01	]
(011)	: 00	--> [ 05	 | 00	 | 09	 | 01	]
(012)	: 03	--> [ 05	 | 00	 | 03	 | 01	]
(013)	: 05	--> [ 05	 | 00	 | 03	 | 01	]
(014)	: 09	--> [ 05	 | 00	 | 03	 | 09	]
(015)	: 08	--> [ 05	 | 08	 | 03	 | 09	]
(016)	: 04	--> [ 05	 | 08	 | 04	 | 09	]
(017)	: 09	--> [ 05	 | 08	 | 04	 | 09	]
(018)	: 01	--> [ 01	 | 08	 | 04	 | 09	]
(019)	: 06	--> [ 01	 | 06	 | 04	 | 09	]
(020)	: 02	--> [ 01	 | 06	 | 02	 | 09	]
(021)	: 06	--> [ 01	 | 06	 | 02	 | 09	]
(022)	: 03	--> [ 01	 | 06	 | 02	 | 03	]
(023)	: 00	--> [ 00	 | 06	 | 02	 | 03	]
(024)	: 09	--> [ 00	 | 06	 | 09	 | 03	]
(025)	: 05	--> [ 00	 | 05	 | 09	 | 03	]
(026)	: 03	--> [ 00	 | 05	 | 09	 | 03	]
(027)	: 05	--> [ 00	 | 05	 | 09	 | 03	]
(028)	: 08	--> [ 08	 | 05	 | 09	 | 03	]
(029)	: 02	--> [ 08	 | 05	 | 02	 | 03	]
(030)	: 06	--> [ 08	 | 05	 | 02	 | 06	]
----------------
Hit rate: 0.2
Page fault rate: 0.8
----------------

----------------
FIFO:
(001)	: 07	--> [ 07	 | -	 | -	 | -	]
(002)	: 05	--> [ 07	 | 05	 | -	 | -	]
(003)	: 03	--> [ 07	 | 05	 | 03	 | -	]
(004)	: 00	--> [ 07	 | 05	 | 03	 | 00	]
(005)	: 06	--> [ 06	 | 05	 | 03	 | 00	]
(006)	: 08	--> [ 06	 | 08	 | 03	 | 00	]
(007)	: 09	--> [ 06	 | 08	 | 09	 | 00	]
(008)	: 01	--> [ 06	 | 08	 | 09	 | 01	]
(009)	: 05	--> [ 05	 | 08	 | 09	 | 01	]
(010)	: 01	--> [ 05	 | 08	 | 09	 | 01	]
(011)	: 00	--> [ 05	 | 00	 | 09	 | 01	]
(012)	: 03	--> [ 05	 | 00	 | 03	 | 01	]
(013)	: 05	--> [ 05	 | 00	 | 03	 | 01	]
(014)	: 09	--> [ 05	 | 00	 | 03	 | 09	]
(015)	: 08	--> [ 08	 | 00	 | 03	 | 09	]
(016)	: 04	--> [ 08	 | 04	 | 03	 | 09	]
(017)	: 09	--> [ 08	 | 04	 | 03	 | 09	]
(018)	: 01	--> [ 08	 | 04	 | 01	 | 09	]
(019)	: 06	--> [ 08	 | 04	 | 01	 | 06	]
(020)	: 02	--> [ 02	 | 04	 | 01	 | 06	]
(021)	: 06	--> [ 02	 | 04	 | 01	 | 06	]
(022)	: 03	--> [ 02	 | 03	 | 01	 | 06	]
(023)	: 00	--> [ 02	 | 03	 | 00	 | 06	]
(024)	: 09	--> [ 02	 | 03	 | 00	 | 09	]
(025)	: 05	--> [ 05	 | 03	 | 00	 | 09	]
(026)	: 03	--> [ 05	 | 03	 | 00	 | 09	]
(027)	: 05	--> [ 05	 | 03	 | 00	 | 09	]
(028)	: 08	--> [ 05	 | 08	 | 00	 | 09	]
(029)	: 02	--> [ 05	 | 08	 | 02	 | 09	]
(030)	: 06	--> [ 05	 | 08	 | 02	 | 06	]
----------------
Hit rate: 0.2
Page fault rate: 0.8
----------------

----------------
LFU:
(001)	: 07	--> [ 07	 | -	 | -	 | -	]
(002)	: 05	--> [ 07	 | 05	 | -	 | -	]
(003)	: 03	--> [ 07	 | 05	 | 03	 | -	]
(004)	: 00	--> [ 07	 | 05	 | 03	 | 00	]
(005)	: 06	--> [ 06	 | 05	 | 03	 | 00	]
(006)	: 08	--> [ 08	 | 05	 | 03	 | 00	]
(007)	: 09	--> [ 09	 | 05	 | 03	 | 00	]
(008)	: 01	--> [ 01	 | 05	 | 03	 | 00	]
(009)	: 05	--> [ 01	 | 05	 | 03	 | 00	]
(010)	: 01	--> [ 01	 | 05	 | 03	 | 00	]
(011)	: 00	--> [ 01	 | 05	 | 03	 | 00	]
(012)	: 03	--> [ 01	 | 05	 | 03	 | 00	]
(013)	: 05	--> [ 01	 | 05	 | 03	 | 00	]
(014)	: 09	--> [ 09	 | 05	 | 03	 | 00	]
(015)	: 08	--> [ 08	 | 05	 | 03	 | 00	]
(016)	: 04	--> [ 04	 | 05	 | 03	 | 00	]
(017)	: 09	--> [ 09	 | 05	 | 03	 | 00	]
(018)	: 01	--> [ 09	 | 05	 | 01	 | 00	]
(019)	: 06	--> [ 09	 | 05	 | 01	 | 06	]
(020)	: 02	--> [ 09	 | 05	 | 01	 | 02	]
(021)	: 06	--> [ 09	 | 05	 | 01	 | 06	]
(022)	: 03	--> [ 03	 | 05	 | 01	 | 06	]
(023)	: 00	--> [ 00	 | 05	 | 01	 | 06	]
(024)	: 09	--> [ 09	 | 05	 | 01	 | 06	]
(025)	: 05	--> [ 09	 | 05	 | 01	 | 06	]
(026)	: 03	--> [ 09	 | 05	 | 03	 | 06	]
(027)	: 05	--> [ 09	 | 05	 | 03	 | 06	]
(028)	: 08	--> [ 09	 | 05	 | 03	 | 08	]
(029)	: 02	--> [ 09	 | 05	 | 03	 | 02	]
(030)	: 06	--> [ 09	 | 05	 | 03	 | 06	]
----------------
Hit rate: 0.23333333333333334
Page fault rate: 0.7666666666666666
----------------

----------------
Opt:
(001)	: 07	--> [ 07	 | -	 | -	 | -	]
(002)	: 05	--> [ 07	 | 05	 | -	 | -	]
(003)	: 03	--> [ 07	 | 05	 | 03	 | -	]
(004)	: 00	--> [ 07	 | 05	 | 03	 | 00	]
(005)	: 06	--> [ 06	 | 05	 | 03	 | 00	]
(006)	: 08	--> [ 08	 | 05	 | 03	 | 00	]
(007)	: 09	--> [ 09	 | 05	 | 03	 | 00	]
(008)	: 01	--> [ 01	 | 05	 | 03	 | 00	]
(009)	: 05	--> [ 01	 | 05	 | 03	 | 00	]
(010)	: 01	--> [ 01	 | 05	 | 03	 | 00	]
(011)	: 00	--> [ 01	 | 05	 | 03	 | 00	]
(012)	: 03	--> [ 01	 | 05	 | 03	 | 00	]
(013)	: 05	--> [ 01	 | 05	 | 03	 | 00	]
(014)	: 09	--> [ 01	 | 09	 | 03	 | 00	]
(015)	: 08	--> [ 01	 | 09	 | 03	 | 08	]
(016)	: 04	--> [ 01	 | 09	 | 03	 | 04	]
(017)	: 09	--> [ 01	 | 09	 | 03	 | 04	]
(018)	: 01	--> [ 01	 | 09	 | 03	 | 04	]
(019)	: 06	--> [ 06	 | 09	 | 03	 | 04	]
(020)	: 02	--> [ 06	 | 09	 | 03	 | 02	]
(021)	: 06	--> [ 06	 | 09	 | 03	 | 02	]
(022)	: 03	--> [ 06	 | 09	 | 03	 | 02	]
(023)	: 00	--> [ 00	 | 09	 | 03	 | 02	]
(024)	: 09	--> [ 00	 | 09	 | 03	 | 02	]
(025)	: 05	--> [ 05	 | 09	 | 03	 | 02	]
(026)	: 03	--> [ 05	 | 09	 | 03	 | 02	]
(027)	: 05	--> [ 05	 | 09	 | 03	 | 02	]
(028)	: 08	--> [ 08	 | 09	 | 03	 | 02	]
(029)	: 02	--> [ 08	 | 09	 | 03	 | 02	]
(030)	: 06	--> [ 08	 | 09	 | 03	 | 02	]
----------------
Hit rate: 0.4482758620689655
Page fault rate: 0.5517241379310345
----------------


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dscn15848078969/article/details/112005695

智能推荐

Python中python-nmap模块的使用_python调用nmap-程序员宅基地

文章浏览阅读3.5w次,点赞8次,收藏54次。 目录python-nmap的安装python-nmap模块的使用portScanner()类环境: python 2.7.13Windows和Linux默认都是不安装python-nmap的,我们得手动安装python-nmap的安装linux:wge t http://xael.org/pages/python-nmap-0.6.1.tar.gz tar..._python调用nmap

android 最新漏洞 root,[原创](Android Root)CVE-2017-7533 漏洞分析和复现_ewqr ewr的博客-程序员宅基地

文章浏览阅读455次。本篇主要是记录一下CVE-2017-7533是什么类型的漏洞,漏洞原理是什么,以及如何触发,又是如何被patch的。进一步,编译源码刷机(此步骤耗时最为长久),在pixel2上复现。此外,进一步思考如果想要从poc到exploit进一步需要做哪些事情?欢迎对这个漏洞感兴趣的同学一起交流学习~0x00 漏洞原理根据对该CVE的描述信息[1]我们可以知道,这是一个在linux kernel中fsnot..._cve-2017-7533

Linux/Centos解决安装oracle11g中文乱码的问题_zysong.ttf-程序员宅基地

文章浏览阅读1.6w次。解决Linux下安装oracle11g中文乱码的问题新建一个目录,上传字体包zysong.ttf到新建的目录,命令如下:#mkdir –p /usr/share/fonts/zh_CN/TrueType#cd /usr/share/fonts/zh_CN/TrueType#chmod –R 75 zysong.ttf配置系统变量为zh_CN.UTF-8,如下图所示:然后启动oracle安装脚本,..._zysong.ttf

jboss连接池,断开后自动重连功能-程序员宅基地

文章浏览阅读1.4k次。最近客户现场的测试环境连的数据库极不稳定,经常会出现需要重新启动数据库的情况, 但是一旦重启数据库 则会出现 提示 ,执行sql错误,原因就是datasource 没有获取新的连接!那么解决办法就是怎样让jboss每次提供连接的时候都给我们可用的最新的连接!文章目录一、环境配置二、配置文件路径三、添加重连标签四、配置截图五、配置后的文件总览六、其他解决办法6.1. Jboss数据库连接断开...

Vcglib使用发生ply相关错误_vcg读取ply-程序员宅基地

文章浏览阅读626次。在测试Vcglib一些功能函数时,发生如下错误:KdTreeTest.obj : error LNK2019: 无法解析的外部符号 "public: unsigned __int64 __cdecl vcg::ply::PropDescriptor::memtypesize(void)const " (?memtypesize@PropDescriptor@ply@vcg@@QEBA_KXZ),该符号在函数 "public: static int __cdecl vcg::tri::io::Importe_vcg读取ply

基于React的垂直选项卡(含锚点定位功能)_react锚点定位-程序员宅基地

文章浏览阅读1.2k次。需求:类似于美团的商家页面,左边是可点击选择的商品品类,右边是按各商品品类分类的商品列表。点击左边某品类时,右边商品列表自动滚动定位到该品类下商品第一个;滚动右边商品列表时,当滚动到某个品类名时自动定位高亮相对应的左边的品类名列表。所用到的插件:基于滚动插件better-scroll完成。用之前需要先了解一下better-scroll文档。所遇到的问题:在实际运用中,但商品品类和商品列表数据量特别大的时候,尤其是商品列表项目中有图片加载和事件绑定时,右侧的商品列表滚动会非常的卡顿。解决问题思路:_react锚点定位

随便推点

pytorch--Softmax回归-程序员宅基地

文章浏览阅读74次。回归与分类回归估计一个连续值分类预测一个离散类别Softmax回归Softmax回归是一个多类分类模型使用Softmax操作子得到每个类的预测置信度使用交叉熵来衡量预测和标号的区别损失函数均方损失绝对值损失函数Huber损失图像分类数据集MNIST数据集是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。我们将使用类似但更复杂的Fashion-MNIST数据集import torchimport torchvisionfrom torch.util

数据库技术:MySQL 多表,外键约束,数据库设计,索引,视图,存储过程,触发器,数据控制,数据备份与恢复_数据库约束和关联技术的应用-程序员宅基地

文章浏览阅读574次。MySQL: Multi-Table, Foreign Key and Database DesignMulti-Table DatabaseIn the development environment, a project usually consists of multiple tables. For Example, in a Online Shopping Mall project, it has user table, category table, product table, order._数据库约束和关联技术的应用

通过opengl es 2.0来实现yuv(NV21)的显示_surfaceflinger直接显示nv21-程序员宅基地

文章浏览阅读5.3k次。基本思路参考如下文章,用opengl es2.0 来实现yuv(NV21)的显示。 http://blog.csdn.net/fu_shuwu/article/details/72972312public static String VERTEX_SHADER = "attribute vec4 vPosition; \n"+_surfaceflinger直接显示nv21

函数调用过程:EBP、ESP等栈帧的变化_c中函数调用时候的压栈顺序,esp ebp指针怎么变化-程序员宅基地

文章浏览阅读3.3k次。从函数调用过程看栈帧的变化_c中函数调用时候的压栈顺序,esp ebp指针怎么变化

SQL SERVER 自动生成 MySQL 表结构及索引 的建表SQL-程序员宅基地

文章浏览阅读321次。SQL SERVER的表结构及索引转换为MySQL的表结构及索引,其实在很多第三方工具中有提供,比如navicat、sqlyog等,但是,在处理某些数据类型、默认值及索引转换的时候,总有些不尽人意并且需要安装软件,懒人开始想法子,所以基于SQL SERVER,写了一个存储过程,可以根据表名直接转换为MySQL的建表建索引的SQL脚本(针对 MySQL Innodb引擎...

android 对话框背景虚化效果,android 对话框Dialog背景虚化效果-程序员宅基地

文章浏览阅读373次。final Dialog exitDialog = new Dialog(this, R.style.FullScreenDialog);LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.exitdialog_layout, null);Button submit = (Button) ll.findViewById(R.id.s...