📄 mainclass.cpp
字号:
// MainClass.cpp: implementation of the CMainClass class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WIN页面置换.h"
#include "MainClass.h"
#include "MainClass.h"
#include "stdio.h"
#include <stdlib.h>
#include "iostream.h"
#include "time.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMainClass::CMainClass()
{
m_program=NULL; //程序,划分为多个页面
m_programsize=0; //用户程序的大小
m_pagenum=0; //划分页面的数目
m_pagesize=1; //页面的大小//默认大小为1k
failnuber=0;
m_scout=NULL;
}
CMainClass::~CMainClass()
{
}
void CMainClass::Oninit()
{
m_program=NULL; //程序,划分为多个页面
m_programsize=0; //用户程序的大小
m_pagenum=0; //划分页面的数目
m_pagesize=1; //页面的大小//默认大小为1k
failnuber=0;
//初始化数据输入以KB为单位
failnuber=0;
extern int m_chengxu,m_ye;
m_pagesize=m_ye;
m_pagesize=m_pagesize*1024;
m_programsize=m_chengxu; //获得程序的大小
m_programsize=m_programsize*1024;
m_pagenum=m_programsize/m_pagesize; //获得页面的数量
//用户程序设置
m_program=new CPage [m_pagenum+1]; //把程序划分为页的形式
for(int i=1;i<=m_pagenum;i++) //设置各个页的页号和偏移地址
{
m_program[i].m_PageNum=i;//设置页号//具有多个页号,页的多小由程序大小控制
m_program[i].m_ExcursionAdress=(i-1)*m_pagesize;//页相对整个程序的逻辑偏移地址.
m_program[i].m_pagesize=m_pagesize; //设置页面大小
}//用户程序处理完毕
//内存初始化设置
for(i=1;i<=10;i++)
{
m_memoryblock[i].m_free=true; //内存为空闲状态
m_memoryblock[i].m_MemoryBlockNum=i;//分配内存块标志号
m_memoryblock[i].m_MemoryAdress=5000+(i-1)*m_pagesize;//物理地址
m_memoryblock[i].m_size=m_pagesize; //设置内存块的大小
}
//页表的初始化
for(int j=1;j<=10;j++)
{
m_pagescheme[j].m_MemoryBlockNum=0;//块表初始化的时,程序没有调入内存。所以为空表
m_pagescheme[j].m_PageNum=0;
m_pagescheme[j].m_UsingFrequency=0;//没有被使用,命中频率当然为0了
}
}
void CMainClass::MainFuntion()
{
//模拟程序启动点
//程序启动把第一块页面调入内存
m_pagescheme[1].m_PageNum=m_program[1].m_PageNum;//页表与程序中的页面对应起来
m_pagescheme[1].m_MemoryBlockNum=m_memoryblock[1].m_MemoryBlockNum;//页表中的内存块号与内存对应起来
m_pagescheme[1].m_UsingFrequency=1;//第一条指令命中第一块页面
m_memoryblock[1].m_free=false; //内存打上使用标志
//读入第一条指令//指令中有4个参数 分别是:
//1在内存中的物理地址,2相对内存块的逻辑偏地址 3.所在内的内存块号 4所在页面的页号
m_CurrptrDictate.m_physicsAdress=5000; //亦是程序的始起地址
m_CurrptrDictate.m_logicAdress=0; //页内第一条指令,偏移地址为0
m_CurrptrDictate.m_memoryblock=1; //当前指令所在的内存块为第一块
m_CurrptrDictate.m_page=1; //当前指令所在的页面为第一页
//共用256条指令来测试//指令地址均为物理地址
long pinprogram=2;//当前指令在程序中的位置
long ninprogram=3;//下一条指令在程序中的位置
// cout<<"当前指令在程序中的位置"<<pinprogram<<endl;
srand( (unsigned)time( NULL ) ); //随机种子
extern int m_text;
//跟踪指令
m_scout=new CDictateScout [m_text+1];
for(int command=1;command<=m_text;command++)
{
int t=0;int m_attemper;//调度情况
t=rand()%1000; //产生0---1000的随机数
if(t<=500) //根据题意。50%为顺序指令
{
ninprogram=pinprogram+1;
cout<<"指令由 "<<pinprogram<<"顺序执行到--->"<<ninprogram<<"\n";
//////////////////////////////////////////////////////////////////////////////
//指令调度中心
m_attemper=Attemper(ninprogram);
////////////////////////////////////////////////////////////////////////////
//数据跟踪系统
//to do add dictate scout
//跟踪当前指令在程序中的位置
m_scout[command].m_CurrptrDictateProgram=pinprogram;
//跟踪当前指令参数
m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
//跟踪下条指令在程序中的位置
m_scout[command].m_NextDictateProgram=ninprogram;
//标志当前程序状态
m_scout[command].m_state=1;//为顺序执行
//跟踪缺页情况
m_scout[command].m_missState=m_attemper;
}//结束50%的顺序指令
else
{
if(t<=750) //25%的指令往后跳
{
//为了防止出现第一条指令往后跳的现象,
if(pinprogram==1)
{
ninprogram=1;
}
else
ninprogram=1+rand()%(pinprogram-1); //第一条指令到当前指令中的任意一条指令
cout<<"指令由 "<<pinprogram<<"往后跳到--->"<<ninprogram<<"\n";
//////////////////////////////////////////////////////////////////////////////
//指令调度中心
m_attemper=Attemper(ninprogram);
////////////////////////////////////////////////////////////////////////////
//数据跟踪系统
//to do add dictate scout
//跟踪当前指令在程序中的位置
m_scout[command].m_CurrptrDictateProgram=pinprogram;
//跟踪当前指令参数
m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
//跟踪下条指令在程序中的位置
m_scout[command].m_NextDictateProgram=ninprogram;
//标志当前程序状态
m_scout[command].m_state=2;//为往后跳
//跟踪缺页情况
m_scout[command].m_missState=m_attemper;
}
else //25%的指令往前跳
{
if(pinprogram==m_programsize)//当前指令达到最后一条指令的时候
{
ninprogram=pinprogram;//指令不可以向前跳
}
else
ninprogram=pinprogram+rand()%(m_programsize-pinprogram);
cout<<"指令由 "<<pinprogram<<"往前跳到--->"<<ninprogram<<"\n";
//////////////////////////////////////////////////////////////////////////////
//指令调度中心
m_attemper=Attemper(ninprogram);
////////////////////////////////////////////////////////////////////////////
//数据跟踪系统
//to do add dictate scout
//跟踪当前指令在程序中的位置
m_scout[command].m_CurrptrDictateProgram=pinprogram;
//跟踪当前指令参数
m_scout[command].m_dictate.m_logicAdress=m_CurrptrDictate.m_logicAdress;
m_scout[command].m_dictate.m_memoryblock=m_CurrptrDictate.m_memoryblock;
m_scout[command].m_dictate.m_page=m_CurrptrDictate.m_page;
m_scout[command].m_dictate.m_physicsAdress=m_CurrptrDictate.m_physicsAdress;
//跟踪下条指令在程序中的位置
m_scout[command].m_NextDictateProgram=ninprogram;
//标志当前程序状态
m_scout[command].m_state=3;//为往前跳执行
//跟踪缺页情况
m_scout[command].m_missState=m_attemper;
}
}//结束指令划分
pinprogram=ninprogram;
m_CurrptrDictate.m_logicAdress=m_NextDictate.m_logicAdress;
m_CurrptrDictate.m_memoryblock=m_NextDictate.m_memoryblock;
m_CurrptrDictate.m_page=m_NextDictate.m_page;
m_CurrptrDictate.m_physicsAdress=m_NextDictate.m_physicsAdress;
}//结束256条指令的测试
// cout<<"第一条指令的物理地址"<<m_CurrptrDictate.m_physicsAdress;*/
}
void CMainClass::FifoAttemper(int m_page,long m_adress)//fifu调度算法
{
//在内存不足的情况下调用fifo算法
//调度过程中仅需要对页表进行操作
//把第一个进来的踢走,其的元素往前走一步,最后进来的放在第十的位置
int page,block,freque;//保存第一页表信息
page=m_pagescheme[1].m_PageNum;
block=m_pagescheme[1].m_MemoryBlockNum;
freque=m_pagescheme[1].m_UsingFrequency;
for(int i=1;i<=9;i++);
{
m_pagescheme[i].m_MemoryBlockNum=m_pagescheme[i+1].m_MemoryBlockNum;//后一个把前面一个覆盖//实现往前走
m_pagescheme[i].m_PageNum=m_pagescheme[i+1].m_PageNum;
m_pagescheme[i].m_UsingFrequency=m_pagescheme[i+1].m_UsingFrequency;
}
//把下一页面调进内存//采代第一页表
//页表配置
m_pagescheme[10].m_PageNum=m_page; //页面
m_pagescheme[10].m_MemoryBlockNum=block; //块
m_pagescheme[10].m_UsingFrequency=1;//
//内存配置
m_memoryblock[10].m_free=false;//打上
//指令配置
m_NextDictate.m_memoryblock=block;
m_NextDictate.m_physicsAdress=m_memoryblock[block].m_MemoryAdress+m_adress;
m_NextDictate.m_logicAdress=m_adress; //已经配置
m_NextDictate.m_page=m_page; //已经配置
}
int CMainClass::Attemper(long DictateInProgramPosition)
{
long position=DictateInProgramPosition;
int block=-1;int page=-1;long logicadress=-1;long physicadress=-1;
//获得分页中的页号和偏移地址
page=position/m_pagesize;
logicadress=position%m_pagesize;
if(logicadress==0)
{
logicadress=m_pagesize-1;
}
else
{
page=page+1;
logicadress=logicadress-1;
}
for(int i=1;i<=10;i++)//扫描页表找到对应的块毫
{
if(page==m_pagescheme[i].m_PageNum)
{ //当前指令在内存中//要找的它所在的内存块号
block=m_pagescheme[i].m_MemoryBlockNum;
m_pagescheme[i].m_UsingFrequency++;
//命中
i=-1;//标志指令已经在内存中
break;
}
}//结束是否在内存扫描//end for
if(i==-1)//已经调入内存block可用
{
cout<<"命中,指令已经在内存\n";
m_NextDictate.m_page=page;
m_NextDictate.m_logicAdress=logicadress;
m_NextDictate.m_memoryblock=block;//得到下条指令的所在内存块号
m_NextDictate.m_physicsAdress=m_memoryblock[block].m_MemoryAdress+logicadress;//指令的物理地址=偏移地址+内存块的物理地址
return 1;
}
else
{
//页面不在内存
int freememoryblock=-1;
for(i=1;i<=10;i++)//扫描页表,看看是否有内存空闲
{
if(m_pagescheme[i].m_UsingFrequency==0)
{
freememoryblock=i;
break;
}
}//结束空闲内存扫描
if(freememoryblock==-1)
{
//没有有空闲内存//在此进行页面置换
cout<<"没有命中,所有的内存已经使用,需要进行页面置换\n";
failnuber++;
FifoAttemper(page,logicadress);
return 3;
}
else
{
//有空闲内存把需要的页面调入内存//利用页表编号与内存编号对应关系有
//页表配置
cout<<"没有命中,但是内存又空闲,需要把页调进内存\n";
failnuber++;
m_pagescheme[freememoryblock].m_PageNum=page; //页面
m_pagescheme[freememoryblock].m_MemoryBlockNum=freememoryblock; //块
m_pagescheme[freememoryblock].m_UsingFrequency=1;//
//内存配置
m_memoryblock[freememoryblock].m_free=false;//打上
m_pagescheme[freememoryblock].m_UsingFrequency=1;
//指令配置
m_NextDictate.m_memoryblock=freememoryblock;
m_NextDictate.m_physicsAdress=m_memoryblock[freememoryblock].m_MemoryAdress+logicadress;
m_NextDictate.m_logicAdress=logicadress; //已经配置
m_NextDictate.m_page=page; //已经配置
return 2;
}//结束内存是否有空判断
}//结束下条指令是否在内存判断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -