29/10/20 ## Memory Overview Computers typically have memory hierarchies: > * Registers > * L1/L2/L3 cache > * Main memory (RAM) > * Disks **Higher Memory** is faster, more expensive and volatile. **Lower Memory** is slower, cheaper and non-volatile. The operating system provides **memory abstraction** for the user. Otherwise memory can be seen as one **linear array** of bytes/words. ### OS Responsibilities * Allocate/de-allocate memory when requested by processes, keep track of all used/unused memory. * Distribute memory between processes and simulate an **indefinitely large** memory space. The OS must create the illusion of having infinite main memory, processes assume they have access to all main memory. * **Control access** when multi programming is applied. * **Transparently** move data from **memory** to **disk** and vice versa. #### Partitioning ![img](/lectures/osc/assets/A.png) ##### Contiguous memory management Allocates memory in **one single block** without any holes or gaps. ##### Non-contiguous memory management models Where memory is allocated in multiple blocks, or segments, which may not be placed next to each other in physical memory. **Mono-programming:** one single partition for user processes. **Multi-programming** with **fixed partitions** * Fixed **equal** sized partitions * Fixed non-equal sized partitions **Multi-programming** with **dynamic partitions** #### Mono-programming > * Only one single user process is in memory/executed at any point in time. > * A fixed region of memory is allocated to the OS & kernal, the remaining memory is reserved for a single process > * This process has direct access to physical memory (no address translation takes place) > * Every process is allocated **contiguous block memory** (no holes or gaps) > * One process is allocated the **entire memory space** and the process is always located in the same address space. > * **No protection** between different user processes required. Also no protection between the running process and the OS, so sometimes that process can access pieces of the OS its not meant to. > > * Overlays enable the **programmer** to use **more memory than available**. ![img](/lectures/osc/assets/B.png) ##### Short comings of mono-programming > * Since a process has direct access to the physical memory, it may have access to the OS memory. > * The OS can be seen as a process - so we have **two processes anyway**. > * **Low utilisation** of hardware resources (CPU, I/O devices etc) > * Mono-programming is unacceptable as **multi-programming is excepted** on modern machines **Direct memory access** and **mono-programming** are common in basic embedded systems and modern consumer electronics eg washing machines, microwaves, cars etc. ##### Simulating Multi-Programming We can simulate multi-programming through **swapping** * **Swap process** out to the disk and load a new one (context switches would become **time consuming**) Why Multi-Programming is better theoretically > * There are *n* **processes in memory** > * A process spends *p* percent of its time **waiting for I/O** > * **CPU Utilisation** is calculated as 1 minus the time that all processes are waiting for I/O > * The probability that **all** *n* **processes are waitying for I/O is *p*^n^ > * Therefore CPU utilisation is given by $1 - p^{n}$ ![cpu_util_form](/lectures/osc/assets/C.png) With an **I/O wait time of 20%** almost **100% CPU utilisation** can be achieved with four processes ($1-0.2^{4}$) With an **I/O wait time of 90%**, 10 processes can achieve about **65% CPU utilisation**. ($1-0.9^{10}$) CPU utilisation **goes up** with the **number of processes** and **down** for **increasing levels of I/O**. ![cpu_util_graph](/lectures/osc/assets/D.png) **Assume that**: > * A computer has one megabyte of memory > * The OS takes up 200k, leaving room for four 200k processes **Then:** > * If we have an I/O wait time of 80%, then we will achieve just under 60% CPU utilisation (1-0.8^4^) > * If we add another megabyte of memory, it would allow us to run another five processes. We can now achieve about **87%** CPU utilisation (1-0.8^9^) > * If we add another megabyte of memory (14 processes) we find that CPU utilisation will increase to around **96%** ##### Caveats * This model assumes that all processes are independent, this is not true. * More complex models could be built using **queuing theory** but we still use this simplistic model to make **approximate predictions** #### Fixed Size Partitions * Divide memory into **static**, **contiguous** and **equal sized** partitions that have a fixed **size and location**. * Any process can take **any** partition. (as long as its large enough) * Allocation of **fixed equal sized partitions to processes is trivial** * Very **little overhead** and **simple implementation** * The OS keeps a track of which partitions are being **used** and which are **free**. ##### Disadvantages * Partition may be necessarily large * Low memory utilisation * Internal fragmentation * **Overlays** must be used if a program does not fit into a partition (burden on the programmer) #### Fixed Partitions of non-equal size * Divide memory into **static** and **non-equal sized partitions** that have **fixed size and location** * Reduces **internal fragmentation** * The **allocation** of processes to partitions must be **carefully considered**. ![process_alloc](/lectures/osc/assets/E.png) **One private queue per partition**: * Assigns each process to the smallest partition that it would fit in. * Reduces **internal fragmentation**. * Can reduce memory utilisation (eg lots of small jobs result in unused large partitions) **A single shared queue:** * Increased internal fragmentation as small processes are allocated into big partitions.