Алгоритм замены страниц FIFO, расчет коэффициента отказов страниц, код в конце статьи и анализ примеров
1. Содержание
Если во время процесса сопоставления адресов обнаруживается, что страница, к которой необходимо получить доступ, отсутствует в памяти, будет сгенерировано прерывание по ошибке страницы. При возникновении страничной ошибки, если в памяти операционной системы нет свободной страницы, операционная система должна выбрать страницу в памяти и переместить ее из памяти, чтобы освободить место для страницы, которая будет передана. Правило, используемое для выбора удаляемой страницы, называется алгоритмом замены страницы.
Смоделируйте управление пейджинговой памятью, осуществите выделение и вызов памяти, а также завершите соответствие между адресной последовательностью виртуальной памяти и физической памятью. Когда в вызове памяти возникает ошибка страницы, передается страница памяти программы. При отсутствии свободных страниц замена страниц осуществляется по алгоритму «первым пришел – первым обслужен» (FIFO).
2. Структура страницы
Структура страницы следующая:
Номер страницы, номер страницы, метка времени (не используется в этом алгоритме, используется в LRU)
имя |
символ |
Функция |
номер страницы |
Page_num |
номер страницы записи |
номер страницы |
Pframe_num |
номер страницы записи |
Алгоритм замены страниц FIFO выбирает страницу, которая остается в основной памяти для самой длинной (т. е. самой старой) замены, то есть страницу, которая первой поступает в память и первой выходит из памяти. Причина в том, что страница, которая сначала была перенесена в память, с большей вероятностью больше не будет использоваться, чем она была только что перенесена в память. Создайте очередь FIFO для хранения всех страниц в памяти. Заменяемые страницы всегда выполняются в начале очереди. Когда страница загружается в память, она вставляется в конец очереди.
Используя линейную таблицу для реализации таблицы страниц, каждый раз, когда необходимо удалить страницу, удаляется первая введенная страница, поэтому страница, которая остается в основной памяти дольше всего, может быть удалена.
Процесс выглядит следующим образом:
3. Пример анализа
В системе управления страницами порядок доступа (строка доступа): 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5, когда количество выделенных страниц равно 3, пожалуйста Подсчитайте количество ошибок страниц, используя следующий (1) алгоритм замещения соответственно, и нарисуйте диаграмму замещения страниц.
(1) ФИФО.
строка доступа | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 1 | 2 | 3 | 4 | 5 |
Страница 1 | 1 | 2 | 3 | 4 | 1 | 2 | 5 | 5 | 5 | 3 | 4 | 4 |
страница 2 | 1 | 2 | 3 | 4 | 1 | 2 | 2 | 2 | 5 | 3 | 3 | |
страница 3 | 1 | 2 | 3 | 4 | 1 | 1 | 1 | 2 | 5 | 5 | ||
Ошибка страницы | да | да | да | да | да | да | да | нет | нет | да | да | нет |
Частота ошибок страницы: 9/12 = 0,75
4. Код выглядит следующим образом:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define MAX_PAGES 20
#define MAX_PFRAME 20
#define INVALID -1
typedef struct {
int page_num;
int pframe_num;
int count;
int timestamp;
}page_type;
page_type page[MAX_PAGES];
typedef struct pf_struct {
int pframe_num;//页面号
struct pf_struct* next;
}pf_type;
pf_type pframe[MAX_PFRAME];
int diseffct = 0;//缺页记录
void InitPage(const int* page_n, const int* pframe_n)
{
int total_vp = *page_n, total_pf = *pframe_n;
int i = 0;
diseffct = 0;
for (i = 0; i < total_vp; i++)//虚拟页
{
page[i].page_num = i;
page[i].pframe_num = INVALID;
page[i].count = 0;
page[i].timestamp = -1;
}
for (i = 0; i < total_pf - 1; i++)
{
pframe[i].next = &pframe[i];
pframe[i].pframe_num = i;
}
pframe[total_pf - 1].next = NULL;
pframe[total_pf - 1].pframe_num = total_pf - 1;
}
double miss_page_rate(int pframe_order[100]) {
int i = 0;
double missrate = 0, count = 0;
while (pframe_order[i] != -1)
{
count++;
i++;
}
missrate = diseffct / count;
return missrate;
}
void menu(int* page_n, int* pframe_n)
{
int a, b;
printf("---------------------------------------------\n");
printf("请输入页面的数量:");
scanf("%d", page_n);
printf("请输入页的数量:");
scanf("%d", pframe_n);
printf("--------------------------------------------\n");
}
int get_input_order(int fprame_order[100], int pframe_n)
{
int p = 0;
int tmp = 0;
printf("请输入访问串(1到%d中的数字,每输入一个数输入一次回车,输入-1表示结束):\n", pframe_n);
while (1)
{
scanf("%d", &tmp);
fprame_order[p] = tmp;
p++;
if (tmp == -1)
{
break;
}
}
return p;
}
int check_all_page(int page_num, int target)
{
int judge = 0;
for (int i = 0; i < page_num; i++)
{
if (page[i].pframe_num == target)
{
judge = 1;
}
}
if (judge == 1)
{
return 1;
}
else
{
diseffct++;//全程序只在本处处理缺页次数
return 0;
}
}
void display(int page_num, int judge)//就是打印出所有的页
{
printf("页面号\t页号\t时间戳\n");
for (int i = 0; i < page_num; i++)
{
printf("%d\t%d\t%d\n", page[i].page_num, page[i].pframe_num, page[i].timestamp);
}
if (judge == 1) {
printf("不缺页\n");
}
else
{
printf("缺页\n");
}
}
void FIFO(int page_num, int pframe_id)//page_num为页的数量,pframe_id为页面号
{
int i, j;
pf_type* p;
for (i = page_num - 2; i >= 0; i--)
{
//page[i + 1].count = page[i].count;
page[i + 1].pframe_num = page[i].pframe_num;
}
page[0].pframe_num = pframe_id;
}
void execute_pagef(int pframe_order[100], int page_num)//page_num为虚拟页的数量,page_n指针和page_num的值一样
{
int i = 0, jugde = 0;
while (pframe_order[i] != -1)
{
printf("************************************\n");
printf("使用页 %d\n", pframe_order[i]);
jugde = check_all_page(page_num, pframe_order[i]);
if (jugde == 1) {//在虚拟页内
i++;
}
else//不在页内就调用页面置换算法
{
FIFO(page_num, pframe_order[i]);
i++;
}
display(page_num, jugde);
}
}
int main()
{
int* page_n = (int*)malloc(sizeof(int));
int* pframe_n = (int*)malloc(sizeof(int));
int pframe_order[100];
int order_num = 0;
menu(page_n, pframe_n);
InitPage(page_n, pframe_n);
order_num = get_input_order(pframe_order, *pframe_n);
execute_pagef(pframe_order, *page_n);
//printf("%d %d\n", *page_n, *pframe_n);
printf("\n缺页率为: %lf", miss_page_rate(pframe_order));
free(page_n);
free(pframe_n);
return 0;
}
5. Запустите следующим образом:
Программа разбита на 5 страниц, в памяти 3 страницы, последовательность доступа 1, 2, 3, 2, 4, 5, 2
Частота отказов страниц: 0,857143