1. トピックの紹介
ジョブの実行プロセスをシミュレートするプログラムを C 言語で設計します。ジョブには合計 320 の命令がある、つまり、そのアドレス空間は 32 ページで、そのすべてのページがまだメモリにロードされていないと仮定します。シミュレーション中、アクセスされた命令がすでにメモリ内にある場合、その物理アドレスが表示され、次の命令が転送されます。アクセスされた命令がメモリにロードされていない場合にはページフォールトが発生するが、このときページフォールトの回数を記録し、該当するページをメモリにロードする必要がある。ジョブの仮想ページが 4 つのメモリ ブロックにロードされている場合は、ページの置換が必要です。最後にその物理アドレスが表示され、次の命令が転送されます。320 個の命令がすべて実行された後、ジョブの実行中に発生したページ フォールト率を計算して表示します。
2. 使用されるデータ構造
/*定义内存中物理块的结构*/
struct memoryblock
{
int pagenumber; // 页面号
int access; // 访问位
int time; // 访问时间
int counter; // 访问次数
};
struct memoryblock M[4];
3. プログラムコードの説明
void init()//初始化内存物理块
void random()//生成随机数
void FIFO()//先进先出置换算法
void CLOCK()//时钟置换算法
void LRU()//最近最久未使用置换算法
void LFU()//最近最少访问置换算法
コアコード:
void random()
{
srand((unsigned)time(NULL));
int cnt = 0;
command[cnt] = rand() % 320;
cnt++;
command[cnt] = command[cnt - 1] + 1;
cnt++;
while (cnt < 320)
{
command[cnt] = rand() % command[cnt - 2];
cnt++;
command[cnt] = command[cnt - 1] + 1;
cnt++;
command[cnt] = rand() % (320 - command[cnt - 1]) + command[cnt - 1];
cnt++;
command[cnt] = command[cnt - 1] + 1;
cnt++;
}
}
void oncefifo(int a)
{
int i;
int p=0;//指向队首的指令
int b = a / 10;
int flag=0;
for (i = 0;i < 4;i++)
{
if (M[i].pagenumber == b)//表示页面在内存中
{
M[i].access = 1;
flag = 1;
break;
}
if (M[i].pagenumber == -1)//表示页面不在内存中,且物理块为空
{
M[i].access = 1;
M[i].pagenumber = b;
p = (p + 1) % 4;
unfindpage++;
flag = 1;
break;
}
}
if (flag == 0)//进行页面置换
{
M[p].pagenumber = b;
M[p].access = 1;
unfindpage++;
}
}
void onceclock(int a)
{
int i;
int p=0;
int b = a / 10;
int flag = 0;
for (i = 0;i < 4;i++)
{
if (M[i].pagenumber == b)//表示页面在内存中
{
M[i].access = 1;
flag = 1;
break;
}
if (M[i].pagenumber == -1)//表示页面不在内存中,且物理块为空
{
M[i].access = 1;
M[i].pagenumber = b;
p = (p + 1) % 4;
unfindpage++;
flag = 1;
break;
}
}
if (flag == 0)
{
while (M[p].access != 0)
{
M[p].access = 0;
p = (p + 1) % 4;
}
M[p].pagenumber = b;
M[p].access = 1;
p = (p + 1) % 4;
unfindpage++;
}
}
void oncelru(int a)
{
int b = a / 10;
int flag = 0;
int i,j;
for (i = 0;i < 4;i++)
{
if (M[i].pagenumber == b)//页面在内存中,更新时间
{
M[i].time = 0;
M[i].access = 1;
flag = 1;
for (j = 0;j < 4;j++)
{
if (j != i&&M[j].pagenumber != -1)//其他未被访问的页面的时间加一
{
M[j].time++;
}
}
break;
}
if (M[i].pagenumber == -1)//页面不在内存中,且物理块为空
{
M[i].time = 0;
M[i].pagenumber = b;
M[i].access = 1;
unfindpage++;
flag = 1;
for (j = 0;j < 4;j++)
{
if (j != i&&M[j].pagenumber != -1)
{
M[j].time++;
}
}
break;
}
}
if (flag == 0)//页面不在内存中,进行置换
{
sort(M, M + 4, cmp1);
M[0].time=0;
M[0].access = 1;
M[0].pagenumber = b;
unfindpage++;
for (j = 1;j < 4;j++)
{
M[j].time++;
}
}
}
void oncelfu(int a)
{
int b = a / 10;
int flag = 1;
int i;
for (i = 0;i < 4;i++)
{
if (M[i].pagenumber == b)//页面在内存中
{
M[i].counter++;
flag = 1;
M[i].access = 1;
break;
}
if (M[i].pagenumber = -1)
{
M[i].counter++;
M[i].pagenumber = b;
M[i].access = 1;
flag = 1;
unfindpage++;
break;
}
}
if (flag == 0)
{
sort(M, M + 4, cmp2);
M[0].pagenumber = b;
M[0].counter=1;
M[i].access = 1;
unfindpage++;
}
}
4. 走行結果
メインメニュー: