1, Experimental content
Simulate the hardware address translation and page missing interrupt in paging storage management, and select the page scheduling algorithm to deal with page missing interrupt.
2, Experimental purpose
In computer system, in order to improve the utilization of main memory, auxiliary memory (such as disk) is often used as the expansion of main memory, so that the sum of all logical address spaces of multi-channel jobs can exceed the absolute address space of main memory. The main memory expanded in this way is called virtual memory. This experiment helps students understand how to realize virtual memory in paging storage management.
3, Experimental topic
There are three questions in this experiment, of which the first question must be done, and you can choose any one of the second and third questions.
Question 1:
Simulate the hardware address translation and page missing interrupt in paging storage management.
(1) paging virtual storage system stores a copy of job information on disk. When a job is selected, the first few pages of the job can be loaded into main memory and started for execution. To this end, when creating a page table for the job, you should specify which pages are already in main memory and which pages have not been loaded into main memory. The format of the page table is:
Page number | sign | Main memory block number | Location on disk |
---|---|---|---|
Flag - used to indicate whether the corresponding page has been loaded into main memory. Flag bit = 1, it indicates that the page is already in main memory; Flag bit = 0 indicates that the page has not been loaded into main memory.
Main memory block number - used to indicate the block number occupied by the page that has been loaded into main memory.
Location on disk - used to indicate where each page of the job copy is stored on disk.
(2) when the job is executed, the logical address in the instruction indicates the page number and unit number stored in the operation participating in the operation. The address conversion mechanism of the hardware looks up the page table according to the page number. If the corresponding flag of the page is "1", it means that the page is already in main memory. At this time, according to the relationship:
Absolute address = block number * block length + unit number
Calculate the address of the main memory unit to be accessed. If the block length is a power of 2, the block number can be used as the high address part and the unit number as the low address part, and the two can be spliced into an absolute address. If the corresponding flag of the accessed page is "0", it means that the page is not in main memory. At this time, the hardware sends a "page missing interrupt" signal. The operating system reads the page information from the disk according to the position of the page on the disk, loads it into main memory, and then re executes this instruction.
(3) design an "address translation" program to simulate the address translation of hardware. When the accessed page is in main memory, it forms an absolute address, but does not simulate the execution of an instruction, but uses the output converted address to replace the execution of an instruction. When the accessed page is not in main memory, the "page number of this page" is output, indicating that a page missing interrupt has occurred. The algorithm of the simulation program is shown in Figure 1.
(4) it is assumed that the length of each block of main memory is 128 bytes. There is a job with seven pages in total. Pages 0 to 3 have been loaded into main memory, and the other three pages have not been loaded into main memory. The page table of this job is:
Page number | sign | Main memory block number | Location on disk |
---|---|---|---|
0 | 1 | 5 | 011 |
1 | 1 | 8 | 012 |
2 | 1 | 9 | 013 |
3 | 1 | 1 | 021 |
4 | 0 | 022 | |
5 | 0 | 023 | |
6 | 0 | 121 |
If the sequence of instructions executed by the job in turn is:
operation | Page number | Unit number | operation | Page number | Unit number |
---|---|---|---|---|---|
+ | 0 | 070 | displacement | 4 | 053 |
+ | 1 | 050 | + | 5 | 023 |
* | 2 | 015 | Save | 1 | 037 |
Save | 3 | 021 | take | 2 | 078 |
take | 0 | 056 | + | 4 | 001 |
- | 6 | 040 | Save | 6 | 084 |
(5) run the designed address conversion program to display or print the operation results. Since only address translation is simulated and the execution of instructions is not simulated, the operations in the above instruction sequence may not be considered.
Second question
First in first out (FIFO) page scheduling algorithm is used to deal with missing page interrupt.
(1) in the paging virtual storage system, when the hardware issues a "page missing interrupt", the operating system is led out to handle the interrupt event. If there is no free block in the main memory, the FIFO page scheduling algorithm can be used to call out the page that first enters the main memory in the job, store it on the disk, and then load the page to be accessed into the block. Modify the flag of the corresponding page in the page table after calling out and loading.
(2) FIFO page scheduling algorithm always eliminates the page that first enters the main memory in the job, so an array can be used to represent the page that the job is already in the main memory. Assume that when the job is selected, the start
m
m
If m pages are loaded into main memory, the elements of the array can be set as
m
m
m. For example:
P
0
,
P
1
,
.
.
.
,
P
m
−
1
P_0,P_1,...,P_{m-1}
P0,P1,...,Pm−1
Each of them
P
i
,
i
=
0
,
1
,
.
.
.
,
m
−
1
P_i,i=0,1,...,m-1
Pi,i=0,1,...,m − 1 represents a page number in main memory. Their initial values are:
P
0
=
0
,
P
1
=
1
,
.
.
.
,
P
m
−
1
=
m
−
1
P_0=0,P_1=1,...,P_{m-1}=m-1
P0=0,P1=1,...,Pm−1=m−1.
With a pointer
k
k
k indicates the position of the page to be eliminated in the array when a new page is to be loaded,
k
k
The initial value of k is "0". When a page missing interrupt occurs, the operating system selects
P
k
P_k
Call up the page indicated by Pk , and then execute:
P
k
=
want
pretend
enter
of
page
number
P_k = page number to load
Pk = page number to load
k
=
k
+
1
m
o
d
m
k=k+1 \mod m
k=k+1modm
Then the loader loads a page of information to be accessed into main memory. Restart the execution of the command just now.
(3) compile a FIFO page scheduler. In order to improve system efficiency, if the page to be eliminated has not been modified during execution, it is not necessary to call out the page (because there is a copy on the disk), but directly load a new page to overwrite it. Therefore, add the flag of "modified" in the page table. If it is "1", it means modified, and if it is "0", it means unmodified. The format is:
Page number | sign | Main memory block number | modify flag | Location on disk |
---|---|---|---|---|
Because it is a simulated scheduling algorithm, it does not actually start the program of outputting one page and loading one page, but uses the output page number and loaded page number to replace the process of calling out and loading one time. The program in the first question is slightly modified and combined with this question. The FIFO page scheduling simulation algorithm is shown in Figure 2
(4) on the disk, the address stored on the disk, the pages loaded into main memory and the sequence of instructions executed in turn are the same as those shown in (4) in question 1. Therefore, the initial page table after adding "modification flag" is as follows:
Page number | sign | Main memory block number | modify flag | Location on disk |
---|---|---|---|---|
0 | 1 | 5 | 0 | 011 |
1 | 1 | 8 | 0 | 012 |
2 | 1 | 9 | 0 | 013 |
3 | 1 | 1 | 0 | 021 |
4 | 0 | 0 | 022 | |
5 | 0 | 0 | 023 | |
6 | 0 | 0 | 121 |
Execute the instruction sequence in turn, run the program you designed, display or print the page number called out and loaded each time, and the value of array P after executing the last instruction.
(5) in order to check the correctness of the program, you can arbitrarily determine a group of instruction sequences, run the designed program and check the execution results.
Question 3
The least recently used (LRU) page scheduling algorithm is used to deal with missing page interrupts.
(1) in paging virtual storage system, when the hardware sends out "page missing interrupt", the operating system is led out to deal with the interrupt event. If there is no free block in the main memory, the LRU page scheduling algorithm can be used to call out the page that first enters the main memory in the job, store it on the disk, and then load the page to be accessed into the block. Modify the flag of the corresponding page in the page table after calling out and loading.
(2) the LRU page scheduling algorithm always eliminates the page in the job that has not been accessed for the longest time, so an array can be used to represent the pages in main memory of the job. The first element in the array always indicates the page number that has just been accessed, so the page that has not been accessed for the longest time is always indicated by the last element. If there are only four free blocks in the main memory and the instruction sequence assumed in prompt (4) of the first question is executed, and the LRU page scheduling algorithm is adopted, the page changes in the main memory are as follows:
3 | 0 | 6 | 4 | 5 | 1 | 2 | 4 | 6 |
---|---|---|---|---|---|---|---|---|
2 | 3 | 0 | 6 | 4 | 5 | 1 | 2 | 4 |
1 | 2 | 3 | 0 | 6 | 4 | 5 | 1 | 2 |
0 | 1 | 2 | 3 | 0 | 6 | 4 | 5 | 1 |
(3) prepare an LRU page scheduler. In order to improve the system efficiency, if the page to be eliminated has not been modified during execution, it is not necessary to call out the page. See tip (3) in question 2. The simulated scheduling algorithm does not actually start the program of outputting one page and loading one page, but uses the output page number and loaded page number instead. Slightly change the program in the first question and combine it with this question. The LRU page scheduling simulation algorithm is shown in Figure 3.
(4) establish an initial page table according to the requirements of prompt (4) in question 1, and add the "modification flag" bit for each page in the table (refer to prompt (4) in question 2). Then run the program you designed according to the sequence of instructions executed in turn, display or print the page number called out and loaded each time, and the value in the array after the last instruction is executed.
(5) in order to check the correctness of the program, you can arbitrarily determine a group of instruction sequences, run the designed program and check the execution results.
(the flow chart on the experimental instruction is wrong!!! Compare carefully!!!)
4, Experimental report
(1) Experimental topic
See above
(2) Description of data structures and symbols used in the program
Data structure:
Logical structure of pages in main memory: sequence table. Physical structure: array. Because it is a simulation run, in order to save memory space, only the PAGE number is saved in main memory, which is stored in int type instead of PAGE, and the complete information of each PAGE is saved. The number of pages M in main memory is 4.
Symbol description:
The structure PAGE represents an item in the PAGE table: it has four attributes: flag flag bit, blockNum main memory block number, diskPos location on disk, and editFlag modification flag.
const int M = 4;//Number of main memory pages int P[M];//Main memory struct PAGE { int flag;//sign int blockNum;//Main memory block number int diskPos;//Location on disk int editFlag;//modify flag PAGE() { flag = blockNum = diskPos = editFlag = 0; } };
Physical structure of page table: array. See the above for the definition and symbol description of page table class.
PAGE page[105];
Physical structure of instruction sequence: array.
Symbol description: the number of pages M in main memory is 4; In FIFO algorithm, the pointer is k; The struct instruct s an operation and has three attributes: op operation, pageNum page number and unitNum unit number.
struct instruct { string op;//operation int pageNum;//Page number int unitNum;//Unit number }; instruct inst[105];
In FIFO algorithm, it initially points to the page of item 0 in main memory.
int k = 0;//Pointer to FIFO
(3) Print a copy of the source program with comments
1. Procedure description
Program description: FIFO CPP completes the second question, LRU CPP completes the third question.
Most of the contents of the two programs are similar. First, the main function allows the user to select the input mode according to the prompt. The user can manually input the page table and instructions, or directly and automatically load the page table and instruction set in the experimental instruction. After initialization, the simulated execution scheduling algorithm.
int main() { int choose; cout << "Choose input:1. auto 2.by hand"; cin >> choose; if (choose == 1) init(); else input(); cpuwork(); }
Execute cpuwork (). In the cpuwork() function, first take the instruction and access the page number according to the flowchart, and check the page table to determine whether the page flag is 1 If the page flag bit is 1, an absolute address is formed, and whether to set the modification flag of the current page to "1" is determined according to whether it is a storage instruction. Then judge whether to follow up instructions until all instructions are completed. When running the scheduling algorithm, the process difference between FIFO algorithm and LRU algorithm is not only the processing of interrupt, but also the page table in main memory needs to be modified every time LRU algorithm runs.
void cpuwork() { for (int i = 0; i < n; i++) { int L = inst[i].pageNum;//Get the page number accessed in the instruction inst[i].print(); if (page[L].flag == 1) {//Page lookup table int addr = page[L].blockNum * blocklen + inst[i].unitNum;//Output absolute address if (inst[i].op == "save")//Is it a stored instruction page[L].editFlag = 1; cout << "absolute address:" << addr << endl; } else { cout << "******interrupt!*****\n"; interrupt(L); i--;//Look up the page table again } } }
LRU. In CPP, the missing page interrupt service simulates the page scheduling of LRU. Call up the page at the bottom of the array and load the new page at the top of the array. Similarly, judge whether to output the current page according to the modification flag. LRU. In CPP, cpuwork() is also slightly different. Every time you visit the main memory, you need to modify the pages in the main memory.
This is the simulated CPU process in the LRU algorithm. The main memory page must be adjusted every time an instruction is executed.
void cpuwork() { for (int i = 0; i < n; i++) { int L = inst[i].pageNum;//Get the page number accessed by the instruction inst[i].print(); if (page[L].flag == 1) { int addr = page[L].blockNum * blocklen + inst[i].unitNum;//Form absolute address if (inst[i].op == "save") page[L].editFlag = 1; cout << "absolute address:" << addr << endl; int pos = 0;//Adjust pages in main memory for (int i = 1; i <m; i++) { if (P[i] == L) { pos = i; break; } } if(pos!=0) for (int i = pos; i >= 1; i--) P[i] = P[i - 1]; P[0] = L; } else { cout << "******interrupt!*****\n"; interrupt(L); i--; } } }
FIFO. In CPP, the page missing interrupt service simulates FIFO page scheduling, and indicates the page to be loaded with pointer k. When calling out a page, judge whether to output the current page according to the modification flag, and then call in a new page.
void interrupt(int L) {//Interrupt processing int j = P[k];//Page to call up if (page[j].editFlag == 1) cout << "out J!" << j << endl;//Call up the current page page[j].flag = 0; cout << "in L" << L << endl;//Call in page P[k] = L; k = (k + 1) % m; page[L].flag = 1;//Load page into main memory }
The interrupt processing of LRU is as follows:
void interrupt(int L) {//Interrupt service int j = P[m - 1];//Bottom page call out if (page[j].editFlag == 1) cout << "out J!" << j << endl;//Call up this page page[j].flag = 0; cout << "in L" << L << endl; P[3] = P[2]; P[2] = P[1]; P[1] = P[0]; P[0] = L;//Adjust pages in main memory page[L].flag = 1; }
2. Complete code
FIFO.cpp
#include<stdlib.h> #include<iostream> using namespace std; const int blocklen = 128; const int M = 4;//Number of main memory pages const int N = 12;//Number of instructions int m = 4; int n = 12; int k = 0;//Pointer to FIFO const int PageSize = 7;//Number of pages required by the job int pageSize = 7; struct PAGE { int flag;//sign int blockNum;//Main memory block number int diskPos;//Location on disk int editFlag;//modify flag PAGE() { flag = blockNum = diskPos = editFlag = 0; } }; int P[M];//Main memory struct instruct { string op;//operation int pageNum;//Page number int unitNum;//Unit number void print() { cout << "Operation:" << op << " Page num:" << pageNum << " Unit num:" << unitNum << endl; } instruct(string _op="",int _pageNum=0,int _unitNum=0 ) { op = _op; pageNum = _pageNum; unitNum = _unitNum; } }; instruct inst[105]; PAGE page[105]; void input() {//Manual input cout << "input the size of pages in main storage:"; cin >> m; cout << "input the size of pages of the process:"; cin >> pageSize; cout << "input the number of instructions:"; cin >> n; for (int i = 0; i < m; i++) { cout << "input flag,blockNum,diskPos:"; int flag, blocknum, diskpos; cin >> flag>>blocknum>>diskpos; page[i].flag = flag; if (flag == 1) { P[k] = i; k = (k + 1) % m; } page[i].blockNum = blocknum; page[i].diskPos = diskpos; } for (int i = 0; i < n; i++) { cout << "input operation,pagenum,unitnum:"; string op; int pagenum, unitnum; cin >> op; cin >> pagenum >> unitnum; inst[i] = { op,pagenum,unitnum }; } k = 0; return; } void init() {//Enter the contents in the experimental instruction page[0].flag = 1; page[0].blockNum = 5; page[0].diskPos = 011; page[1].flag = 1; page[1].blockNum = 8; page[1].diskPos = 012; page[2].flag = 1; page[2].blockNum = 9; page[2].diskPos = 013; page[3].flag = 1; page[3].blockNum = 1; page[3].diskPos = 021; page[4].diskPos = 022; page[5].diskPos = 023; page[6].diskPos = 121; inst[0] = { "+",0,70 }; inst[1] = { "+",1,50 }; inst[2] = { "*",2,15 }; inst[3] = { "save",3,21 }; inst[4] = { "get",0,56 }; inst[5] = { "-",6,40 }; inst[6] = { "move",4,53 }; inst[7] = { "+",5,23 }; inst[8] = { "save",1,37 }; inst[9] = { "get",2,78 }; inst[10] = { "+",4,1 }; inst[11] = { "save",6,84 }; P[0] = 0; P[1] = 1; P[2] = 2; P[3] = 3; } void interrupt(int L) {//Interrupt processing int j = P[k];//Page to call up if (page[j].editFlag == 1) cout << "out J!" << j << endl;//Call up the current page page[j].flag = 0; cout << "in L" << L << endl;//Call in page P[k] = L; k = (k + 1) % m; page[L].flag = 1;//Load page into main memory } void cpuwork() { for (int i = 0; i < n; i++) { int L = inst[i].pageNum;//Get the page number accessed in the instruction inst[i].print(); if (page[L].flag == 1) {//Page lookup table int addr = page[L].blockNum * blocklen + inst[i].unitNum;//Output absolute address if (inst[i].op == "save")//Is it a stored instruction page[L].editFlag = 1; cout << "absolute address:" << addr << endl; } else { cout << "******interrupt!*****\n"; interrupt(L); i--;//Look up the page table again } cout << "********************************\npages in main storage\n"; for (int i = 0; i <m; i++) cout << "Page num:" << P[i] << " Block num:" << page[P[i]].blockNum << " Edit Flag:" << page[P[i]].editFlag <<" Disk pos:" << page[P[i]].diskPos <<endl; cout << "********************************\n\n" cout << "********************************\npages of the work\n"; for (int i = 0; i <pageSize; i++) cout << "Page num:" << i <<" flag:" <<page[i].flag<<" Block num:" << page[i].blockNum << " Edit Flag:" << page[i].editFlag <<" Disk pos:" << page[i].diskPos <<endl; cout << "********************************\n\n"; } } int main() { int choose; cout << "Choose input:1. auto 2.by hand"; cin >> choose; if (choose == 1) init(); else input(); cpuwork(); }
LRU.cpp
#include<stdlib.h> #include<iostream> using namespace std; const int blocklen = 128; const int M = 4;//Number of main memory pages const int N = 12;//Number of instructions int m = 4; int n = 12; int k = 0;//Pointer to FIFO const int PageSize = 7;//Number of pages required by the job int pageSize = 7; struct PAGE { int flag;//sign int blockNum;//Main memory block number int diskPos;//Location on disk int editFlag;//modify flag PAGE() { flag = blockNum = diskPos = editFlag = 0; } }; int P[50];//Main memory struct instruct { string op;//operation int pageNum;//Page number int unitNum;//Unit number void print() { cout << "Operation:" << op << " Page num:" << pageNum << " Unit num:" << unitNum << endl; } instruct(string _op = "", int _pageNum = 0, int _unitNum = 0) { op = _op; pageNum = _pageNum; unitNum = _unitNum; } }; instruct inst[105]; PAGE page[105]; void input() { cout << "input the size of pages in main storage:"; cin >> m; cout << "input the size of pages of the process:"; cin >> pageSize; cout << "input the number of instructions:"; cin >> n; for (int i = 0; i < m; i++) { cout << "input flag,blockNum,diskPos:"; int flag, blocknum, diskpos; cin >> flag >> blocknum >> diskpos; page[i].flag = flag; if (flag == 1) { P[k] = i; k = (k + 1) % m; } page[i].blockNum = blocknum; page[i].diskPos = diskpos; } for (int i = 0; i < n; i++) { cout << "input operation,pagenum,unitnum:"; string op; int pagenum, unitnum; cin >> op; cin >> pagenum >> unitnum; inst[i] = { op,pagenum,unitnum }; } k = 0; return; } void init() {//Page table on the experimental instruction page[0].flag = 1; page[0].blockNum = 5; page[0].diskPos = 011; page[1].flag = 1; page[1].blockNum = 8; page[1].diskPos = 012; page[2].flag = 1; page[2].blockNum = 9; page[2].diskPos = 013; page[3].flag = 1; page[3].blockNum = 1; page[3].diskPos = 021; page[4].diskPos = 022; page[5].diskPos = 023; page[6].diskPos = 121; inst[0] = { "+",0,70 }; inst[1] = { "+",1,50 }; inst[2] = { "*",2,15 }; inst[3] = { "save",3,21 }; inst[4] = { "get",0,56 }; inst[5] = { "-",6,40 }; inst[6] = { "move",4,53 }; inst[7] = { "+",5,23 }; inst[8] = { "save",1,37 }; inst[9] = { "get",2,78 }; inst[10] = { "+",4,1 }; inst[11] = { "save",6,84 }; P[0] = 0; P[1] = 1; P[2] = 2; P[3] = 3; } void interrupt(int L) {//Interrupt service int j = P[m - 1];//Bottom page call out if (page[j].editFlag == 1) cout << "out J!" << j << endl;//Call up this page page[j].flag = 0; cout << "in L" << L << endl; P[3] = P[2]; P[2] = P[1]; P[1] = P[0]; P[0] = L;//Adjust pages in main memory page[L].flag = 1; } void cpuwork() { for (int i = 0; i < n; i++) { int L = inst[i].pageNum;//Get the page number accessed by the instruction inst[i].print(); if (page[L].flag == 1) { int addr = page[L].blockNum * blocklen + inst[i].unitNum;//Form absolute address if (inst[i].op == "save") page[L].editFlag = 1; cout << "absolute address:" << addr << endl; int pos = 0;//Adjust pages in main memory for (int i = 1; i <m; i++) { if (P[i] == L) { pos = i; break; } } if(pos!=0) for (int i = pos; i >= 1; i--) P[i] = P[i - 1]; P[0] = L; } else { cout << "******interrupt!*****\n"; interrupt(L); i--; } cout << "********************************\npages in main storage\n"; for (int i = 0; i < m; i++) cout << "Page num:" << P[i] << " Block num:" << page[P[i]].blockNum << " Edit Flag:" << page[P[i]].editFlag << " Disk pos:" << page[P[i]].diskPos << endl; cout << "********************************\n\n"; cout << "********************************\npages of the work\n"; for (int i = 0; i <pageSize; i++) cout << "Page num:" << i <<" flag:" <<page[i].flag<<" Block num:" << page[i].blockNum << " Edit Flag:" << page[i].editFlag <<" Disk pos:" << page[i].diskPos <<endl; cout << "********************************\n\n"; } } int main() { int choose; cout << "Choose input:1. auto 2.by hand"; cin >> choose; if (choose == 1) init(); else input(); cpuwork(); }
(4) Program running results
Print the initial page table, call out (when you want to call out a page) and the loaded page number each time, and the page number in main memory after executing the last instruction (i.e. the value of the array).
FIFO algorithm
The figure shows the initial page table, which is completely consistent with the experimental instruction.
When the 5th instruction is executed and page 0 is called up, page 6 is loaded. Since the modification flag bit is 0, it is not necessary to call out "0" and output it.
When the sixth instruction is executed and page 1 is called up, page 4 is loaded. Since the modification flag bit is 0, it is also unnecessary to call out "1" and output it.
When the 7th instruction is executed and page 2 is called up, page 5 is loaded. Since the modification flag bit is 0, it is also unnecessary to call out "2" and output it.
When the 8th instruction is executed and page 3 is called up, page 1 is loaded. Since the modification flag bit is 1, you need to output "3".
When the 9th instruction is executed and page 6 is called up, page 2 is loaded. Since the modification flag bit is 0, it is also unnecessary to call out "6" and output it.
When the last instruction is executed and page 4 is called up, page 6 is loaded. Since the modification flag bit is 0, it is also unnecessary to call out "4" and output it. At the same time, figure 10 is also the page number in main memory when the last instruction is executed.
LRU algorithm
The figure shows the initial page table. No matter which algorithm is adopted, it is completely consistent with the experimental instruction.
The figure shows the first interrupt. Call out 1 at the bottom of the array and call in 6. And modify the situation in the stack.
The figure shows the second interrupt. Call out 2 at the bottom of the array and call in 4. And modify the situation in the stack.
The figure shows the third interrupt. Call out 3 at the bottom of the array and call in 5. And modify the situation in the stack. Since the modification flag bit of 3 is 1, 3 needs to be output.
The figure shows the fourth interrupt. Call out 0 at the bottom of the array and call in 1. And modify the situation in the stack.
The figure shows the fifth interrupt. Call out 6 at the bottom of the array and call in 2. And modify the situation in the stack.
The figure shows the sixth interrupt. Call out 5 at the bottom of the array and call in 6. And modify the situation in the stack.
The page number left in main memory after all instructions are run.
5, Thinking questions
If you are interested, you can do both page scheduling algorithms and compare the efficiency of the two scheduling algorithms (which scheduling algorithm produces fewer page breaks); Analyze which scheduling algorithm is more favorable under what circumstances?
As mentioned above, two page scheduling algorithms have been implemented and run. Among them, the FIFO algorithm produces 6 page missing interrupts, and the page missing interrupt rate is 6 / 12 = 50%. LRU algorithm produces 6 page missing interrupts, and the page missing interrupt rate is 6 / 12 = 50%. For the data given in the experimental instruction, the efficiency of the two algorithms is the same. The number of page missing interrupts is the same. In most cases, especially when executing circular statements, LRU algorithm is more favorable.