MeMOry RePlacement alGorithms
at main 149 lines 4.9 kB view raw view rendered
1# MeMOry page RePlacement alGorithms (MMORPG) 2 3This project had several goals: 4- find what each of the page replacement algorithms (PRA) share in common. 5- try to use functional programming patterns to implement each algorithm[1]. 6- implement the algorithms correctly. 7 8Some caveats: 9- [1]: I tried avoiding mutation and loops. For example, the only use of `for` 10 loops happens in "list-comprehensions", and list-comprehensions are 11 equivalent to `list(map(...))`. 12 13The first item was rather simple, after implementing all three algorithms, I 14have come to the conclusion: 15> All PRA's are basically a function that, depending on the current state of the 16> memory, take in a page access and return a new state of memory. 17 18Because of this, the "prototype" for these functions is the following: 19```python 20def optimal(state: State, access: tuple[str, int]) -> State: 21 pass 22 23def second(state: State, access: tuple[str, int]) -> State: 24 pass 25 26def wsclock(state: State, access: tuple[str, int]) -> State: 27 pass 28``` 29 30They are all functions that return a new state, given a previous state and a 31memory access. Executing these algorithms then consists of running each 32algorithm on the sequence of accesses while accumulating some state. For this, I 33implemented the usual `fold` algorithm used in many other programming languages: 34 35```python 36#Folding function. 37def fold[T, U](f: Callable[[U, T], U], z: U, l: list[T]) -> U: 38 # This is a simple for loop that accumulates a value and then returns it. 39 for x in l: 40 z = f(z, x) 41 return z 42``` 43 44In this case `z` is the state, `f` is the accumulating function and `l` is the 45sequence that is used. 46 47Then, for the implementation of each algorithm. 48 49## Second chance 50 51The algorithm basically has two parts: 52- the access' page is in the page table: and this is considered a page hit 53- the access' page is not in the page table: this is a page fault and the page 54 must be inserted into the page table. If the page table is full, then a page 55 must be evicted. 56 57This process will seem very similar to the other algorithms. 58 59```python 60def second(state: State, access: tuple[str,int]) -> State: 61 page = access[1] 62 if page in state.page_table: 63 return state.modify(page, True).hit() 64 else: 65 if len(state.page_table) == state.physical_capacity: 66 return state.evict().insert(page).fault() 67 else: 68 return state.insert(page).fault() 69``` 70 71## Optimal 72 73This is a very similar algorithm to the previous. In this case, thhe only 74difference is that we use the method `update()` to update the indices that are 75used to decide what page to evict. 76 77```python 78def optimal(state: State, access: tuple[str,int]) -> State: 79 page = access[1] 80 if page in state.page_table: 81 return state.update().hit() 82 else: 83 if len(state.page_table) == state.physical_capacity: 84 return state.evict().insert(page).update().fault() 85 else: 86 return state.insert(page).update().fault() 87``` 88 89## WSClock 90 91This was also very similar to the previous two, except that there is a method 92for modifying a page depending on the access mode 93(`modify(page, True, mode == "W")`) and a method for updating the list of 94indices (`update()`). 95 96```python 97def wsclock(state: State, access: tuple[str,int]) -> State: 98 mode, page = access 99 assert mode in {"R", "W"} 100 if page in state.page_table: 101 return state.modify(page, True, mode == "W").update().hit() 102 else: 103 if len(state.page_table) == state.physical_capacity: 104 return state.evict().insert(page).update().fault() 105 else: 106 return state.insert(page).update().fault() 107``` 108 109## General 110 111Then, each state must implement these algorithms. The details for the 112implementations of these algorithms are all in their respective files. Most of 113the heavy lifting for these algorithms occurs inside the implementation of 114`evict()` since that is where most of these algorithms differ. 115 116One more thing, each algorithm's file is accompanied with an untyped version of 117that file, suffixed with `*_bare.py`. This is useful in case your python 118implementation doesn't use the fancier type hints that more modern versions of 119Python have. 120 121# Running 122 123To run the second-chance algorithm: 124 125```sh 126python second.py number_of_pages file_path 127``` 128 129To run the optimal algorithm: 130 131```sh 132python optimal.py number_of_pages file_path 133``` 134 135To run the WSClock algorithm: 136 137```sh 138python wsclock.py number_of_pages tau file_path 139``` 140 141# References 142 143I would like to thank Yadiel Mercado, Uriel Fuentes, for helping me debug and 144implement the algorithms; Jantony Velazquez for helping me understand functional 145programming patterns better; and Sebastian Ramirez for giving me advice on how 146to make my code more readable. 147 148I enjoyed working on this project a lot, so if you have any questions, feel 149free to contact me!