Assignment 2 Memory Management Steps To Do 1. Keep a check on whether the supplied input is of required format or not 2. Simulate a paging system with user defined page size 3. Access the memory locations as described in programtrace 4. Implement demand paging and prepaging 5. Implement three different page replacement algorithms 6. Output 7. Write report 1. Check the Input format A typical input would be: ./memorysimulator programlist programtrace 2 lru 0 arg0 : program name arg1: programlist file arg2: programtracefile arg3: page size arg4: page replacement algorithm selected arg5: prepaging=1 / demand-paging=0 In case of error in input, print an error message 2 . Simulate a Paging System Main memory is 512 locations Store page size: one of the inputs provided by the user Read the programlist file and parse the values : Assign a unique number to each virtual page (Process# + VP#) To maintain unique number for each page, after you finish parsing program 0 which has pages 1...n, don't restart your number. Program1 should have pages n+1.....m , program 2 should have m+1....o.. etc. Store all these pages for each program in a vector or an array of arrays. Store each program size which is read from programlist file Implement page tables for each program Default load memory initially Programlist file Program No. Program Size Page Size Pages Needed Unique Identity No. 0 501 2 251 0~250 1 251 2 126 251~376 2 401 2 201 377~577 3 301 2 … … 4 601 2 … … 5 351 2 … … 6 431 2 … … 7 651 2 … … 8 346 2 … … 9 551 2 … … Page Table Implementation Maintain separate page table for each program Maintain Page table for main memory which makes it easier to keep track of the pages which are in main memory. The concept of maintaining page table is helpful in real time systems since it helps in searching which pages are in memory very fast. With each page replacement, the page table for main memory should be updated. Unique Identity of Each Page • Already Assign each page of program with a unique number (with respect to all pages in all page tables), so you can quickly determine if it is present in main memory or not. • Page table for each program can use two variables: – Relative Page No. – Absolute (Physical) Page No.: unique identity No. For example, Relative Page No. R= (the location of the program you want to access)/pagesize Absolute Page No. A= the Rth page of the current program in page table • Page table for main memory only has Absolute Page No. Default Load Memory Each program will be allocated (Total no. of page frames / no. of programs) number of pages initially. Thus each program gets a contiguous chunk of memory. For example, if there are 10 programs and page size=1, each program will get 512/10 51 pages. Load pages of each program in the fixed chunk starting from the first page of the program. If a program’s size is less than the chunk it is allocated, leave a blank spot in the extra space it is allocated. 3. Access Memory Locations as Described in Programtrace Read the programtrace file and parse the values: Each entry says the program number and the memory location it wants to access, parse that value to an absolute page no. Increase a global counter (TimeStamp) with each page access If the page that contains the required location is in main memory (resident), access it. If LRU, assign global counter to that page’s timestamp If Clock, used bit = 1 (or true) Else a page fault occurs . Handle page fault – Demand/prepaging to bring the page to memory Use the appropriate Page Replacement algorithm (FIFO, LRU, Clock) to pick a page for replacement 4. Implement Demand & Prepaging User chooses either demand (0) or prepaging (1) If demand paging, just bring the requested page to memory If prepaging, also bring 2 pages (the faulted page + the next page) However, count it as only 1 pagefault. Note: If the requested page is the last page of the program, bring only that page For the correct implementation of the Page Replacement Algorithms, you need to check if the second page is already resident. If so, you need to update the LRU and Clock information accordingly. 5. Implement different Page Replacement algorithms Maintain a global counter (TimeStamp): increment it with each page access, (irrespective of which page is being accessed) to keep track of the oldest memory location accessed. FIFO: Maintain a timestamp array associated with each page frame in memory. CLOCK: Maintain an array (used bit) for each page frame in memory when a page in memory is accessed, used bit = 1 (or true) LRU: Maintain a timestamp array and when a page is accessed, save the current global counter value as its timestamp. LRU LRU works on the idea that pages that have been used recently are most likely to be used in the near future. If a page is needed to be swapped out, it chooses the Least Recently Used page for replacement. Main idea: find the page with the smallest timestamp. FIFO low-overhead algorithm that requires little bookkeeping on the part of the OS When a page needs to be replaced, the oldest page (in terms of its stay in main memory) is selected. FIFO is cheap and intuitive, but it performs poorly in practical applications. LRU VS. FIFO • Similarity: find the oldest timestamp page of main memory • Difference: if LRU is used, when a page in main memory is accessed, the current program counter will be assigned to timestamp of the page; while FIFO doesn’t do anything when a page in main memory is accessed. CLOCK The clock algorithm keeps a circular list of pages in memory "hand" (iterator) points to the oldest page (smallest timestamp) in the list (similar part with LRU and FIFO) When a page fault occurs and no empty frames exist, then the used bit is inspected at the hand's location If used bit is 0, the new page is put in place of the page the "hand" points to Else, the used bit is cleared and the clock hand is incremented and the process is repeated until a page is found for replacement. 6. Output Record the number of page faults. Number of page faults is the main output. Don’t forget to print error messages for inappropriate inputs. It is a good idea to also print the program sizes and the page replacement policy selected. • The output format recommended for your program is: /************************************************** Page Size: 8 Replacement Algorithm: Clock Based Policy Paging Policy: Demand Paging Total Page faults: 78400 /************************************************** You may test the correctness of your implementation by checking if your results are close to the following: Pagesize = 2 LRU (prepaging disabled) = 87211 page faults CLOCK (prepaging disabled) = 90282 FIFO (prepaging disabled) = 92441 Pagesize = 2 LRU (prepaging enabled) = 62207 page faults CLOCK (prepaging enabled) = 67601 FIFO (prepaging enabled) = 67115 Pagesize = 8 LRU (prepaging disabled) = 65212 page faults CLOCK (prepaging disabled) = 76401 FIFO (prepaging disabled) = 77530 Pagesize = 8 LRU (prepaging enabled) = 60417 page faults CLOCK (prepaging enabled) = 82960 FIFO (prepaging enabled) = 82812 7. Report Writing After successful implementation, try running each algorithm (clock, LRU, FIFO) with page sizes 1,2,4,8, and 16. Obtain simulation results for both demand paging and prepaging. Thus obtain 10 measurements (runs) for each page replacement policy (LRU, clock, FIFO) . 10 Runs for LRU 1 Prepaging 2 LRU 4 8 16 Demand Paging Plot all these results on a graph (x:page size, y: page faults). It will have 6 curves altogether (each with a different legend). Write a 1-2 page report detailing your findings, including a discussion of complexity of each algorithm vs. its performance. Also, explain how prepaging affects the performance. Discussion in Report Discuss what you expected to see vs. what you actually saw. If the results do not mirror your expectations / textbooks claims, discuss why. Discuss the relative complexity of programming each algorithm. Discuss how the data might have changed if a completely random memory access trace had been supplied. Program Flow Chart Start Check input format: arguments<6, instructions pos up Read program list file: # of program and size Make page table for each program: Relative page and Absolute page Combine all page tables to a vector (array of array) Default load main memory with each program equally Default assign timestamp array to each page in main memory based on LRU, FIFO and Clock (clock array for used bit) Read program trace file: # of program and location Increase program counter with each page access Calculate relative page, refer to page table, get absolute page Find in Main Mem? If LRU, assign program counter to that page’s timestamp If clock, assign true or 1 to used bit in clock array Pagefault processing Page fault processing: Page fault number ++ LRU: (when page is found in main, time stamp = program clock) Find the smallest timestamp (oldest) in main and replace If Demand, 1 page brings in; if prepage, 2 pages bring in FIFO: CLOCK: Find the smallest timestamp(oldest) in main and replace Find the smallest timestamp(oldest) in main, check used bit in clock array in a cycle way, if true, assign false; else find and replace If Demand, 1 page brings in; if prepage, 2 pages bring in If Demand, 1 page brings in; if prepage, 2 pages bring in