---
# System prepended metadata

title: Ch.5-4 Virtual Memory
tags: [計算機組織, Computer Organization]

---

# Ch.5-4 Virtual Memory
###### tags: `Computer Organization`, `計算機組織`
## 前言
* virtual memory是為了讓程式有「<font color=blue>自己在用全部、完整的記憶體＆擁有連續的記憶體位址</font>」的錯覺
* 為了讓程式在**實體**記憶體中的任何一個位子都可以運作
當程式要存取記憶體時，就會給他一個virtual address space，這個虛擬記憶體就只有這個程式可以用；程式<font color=red>實際</font>要執行時，才會放到physical address space
* 所以實作virtual memory的時候，要進行「轉換」，讓他可以對應到physical memory位址
* 實際上，disk相對memory就相當於memory相對cache
    只是cache只用hardware控制（cache controller）
    而virtual memory的管理，需要CPU hardware + OS合作
## 名詞
1. page：virtual memory system中，block放在disk的稱呼
2. frame：virtual memory system中，block放在physical memory的稱呼
3. page fault：virtual memory要的資料不在physical memory中，而在disk中的狀況（如CPU在cache找不到資料，要去memory找，稱為miss的概念）

![](https://i.imgur.com/VxlRZHp.png)
```
virtual memory system就是在決定要把disk中的誰放到physical memory中，
或是把physical memory中的誰給replace掉
```
## Address Translation
![](https://i.imgur.com/Udzo0HO.png)
:::info
virtual memory都會對應到某個位址，可能是physical memory或disk的。
當一個程式要執行時，如果他的virtual memory address對應到...
* physical memory的某個frame（白色部分），很好
* disk（灰色部分），則稱為page fault
:::
![](https://i.imgur.com/wD6Eii4.png)
:::info
virtual address sapce的大小是**由處理器的定址能力決定的**
physical address spcae則是依據系統特性（看你掛多大的RAM"吧"）

這個例子中：virtual address有32bit；而physical address為1G大，需要30個bit表示
因為page size是4K，所以virtual address跟physical address都有12bit的page offset（用來表示所需資料在這個page/frame中的哪一個位子）
剩下的bit用來儲存page number

**注意**：因為有可能無法在physical memory中找到資料，所以virtual address也會存disk中資料的位址
:::
### Paging
```
做address translation就好比mapping
要把virtual address映射到正確的physical address
```
![](https://i.imgur.com/P0uw7cl.png)
:::info
圖中流程：
有個程式要動作了，processor產生一個virtual address
(粉框)然後這個virtual address去找對應的physical address
如果有找到，就走a'那條路，直接去physical memory拿資料
如果沒有，就是發生page fault，走$\Phi$那條路，去disk找資料放physical memory
:::
## Basic Issues in Virtual Memory
因為virtual memory也是memory hierarchy的一環
所以也需要討論如`block placement`、`block identification`、`block representation`、`write strategy`的問題
只是有點小改變，變成：
1. Size of data blocks：如何選擇block的大小
2. Placement policy：page應該被放在memory的哪一個位置
3. Replacement policy：physical frame不足時，如何決定換掉誰
4. Demand load policy：把disk的資料搬到frame的時機
    （如OS中的demand paping - 需要時才把東西搬進去）
## Block Size and Placement Policy
因為CPU存取一次disk需要花`數百萬個cycle`，所以發生一次page fault的miss penalty很大
為了減少miss penalty，virtual memory中的page size應該要足夠大
為了減少page fault的機率，採用<font color=red>fully associative</font>的placement policy
### Address Translation Mechanism
![](https://i.imgur.com/85Kg4SX.png)
為了記錄每一個virtual memory對應的位址，需要藉助**table**（圖中右上）
這個table稱為page table，index由virtual memory的page編號表示；資料由virtual memory對應於physical中的哪一個frame表示（-表示在disk中）
圖中下半部分的粉紅框，就是一個轉換virtual跟physical的機制，要借助table完成
#### Example
![](https://i.imgur.com/DiLjVLy.png)
整個virtual memory的大小是$2^{20}$bytes
每個page的大小是$2^{10}$bytes
問virtual address = 7414的狀況下，在physical memory的哪裡？
:::info
1. $7414/2^{10} = 7414/1024 = 7$
    目的在於"求出位於第幾的virtual page"
2. 根據table發現，第7個virtual page對應第5個physical frame
3. $7414\ mod\ 1024 = 246$
目的在於"<font color=blue>求出7414會分布在一個page/frame中的哪個位址</font>"
4. $1024*5 + 246 = 5366$
目的在於"<font color=blue>求出實際位於physical memory的位址</font>"
    因為是在physical的第5個frame其中第246個位子，所以這樣算。
:::
### Page Tables
<font color=red>！！**page table很重要**！！</font>

當CPU產生一組virtual address之後，只要用address / page size就可以得出"是在哪一個page"
由此當作index，藉由查詢table，得到frame的編號
並可以由硬體支援，提供一個page table register，指向page table的base address
有了base跟index，就可以把所有的virtual page轉換成physical frame

* 如果找得到對應的frame，就可以把所需資料取出來
    且這個page table entry還會存有reference/dirty bit等可供參考
* 如果都沒有對應的frame，page table也可以指引要去哪裡才能找到disk上的page
![](https://i.imgur.com/6s37x3W.png)
### Page Fault: What Happens When You Miss?
硬體<font color=blue>無法</font>直接處理page fualt的狀況，所以會由軟體(OS)解決（更準確地說是「不建議用硬體處理」，實務上也不會用硬體處理）
:::info
原因：
1. CPU存取一次硬碟，要數百萬個cycle，很久
    但是由智慧/複雜的程式完成，時間花費比較少，也能減少page fault rate
2. OS可以將發生page fault的process進行context-switch
    （放入waiting queue，拿別的process到ready queue；等到page fault的狀況結束，才把原本的process重新放回ready queue）
:::
### Handling Page Faults
OS處理page fault步驟：
1. 挑出一個frame丟掉（存回disk，以騰出空間給下一個page）
2. 把page從disk中拿出，載入frame
3. 更新page table
4. 交還控制權給硬體，繼續動作

要做到以上事情，OS必須要：
1. 在disk上騰出一塊區域，能放下一個process所有的page
2. 具有"可以紀錄page在disk哪個位子"的資料結構（如page table），才能有效地找資料
3. 為了要做replacement，要具有"可以記錄process在frame的位址"的資料結構
## Page Replacement and Writes
* 因為存取disk要花費太長時間，所以為了減少要去存取的機會，就要減少page fualt rate。於是會選擇在replacement policy上採用**LRU**
* write strategy的部分也不可能選擇write through，因為這將花掉非常多的時間；所以會採用write-back（用dirty bit紀錄page是否被修改過）
### Page Replacement: 1-bit LRU
概念跟OS中的second-chance algorithm很相似

![](https://i.imgur.com/F1CvSzA.png)
## Impact of Paging - Huge Page Table
:::warning
virtual memory system中很重要的議題：
**page table size**
:::
假設page的狀況如下：
![](https://i.imgur.com/h6opMbl.png)
則每個process的page table都是4MB大，且必須為連續
倘若有很多process同時在執行，將會占滿整個physical memory
所以要如何決定page table size，是很重要的
以下幾個方法：
1. 限制一個小的size，如果不夠用再擴增
2. 給定兩個table，一個從記憶體位址低的往高的成長，另一個則反過來
3. hashing（inverting page table）
4. multi-level page table：把page table切成好幾個小段，就可以不連續
5. paged page table：把page table切成很多小小的一塊，每一塊就是一個page（可以融入virtual memory system方便管理）
### Hashing: Inverted Page Tables
* inverted page table：記錄<font color=blue>在physical frame</font>的page資訊
* page table：紀錄<font color=blue>一個process所擁有的、完整的page所在</font>的資訊
:::warning
inverted page table不是用來取代page table的
inverted page table最大的好處是「節省要用的physical memory」
因為可以把page table存在disk，physical memory存inverted page table就好
:::
![](https://i.imgur.com/8t0KgUd.png)
:::info
運作方式：
CPU一樣會產生一個virtual address
然後會經過一個hash function存到inverted page table中
當process需要某個資料的時候，優先從inverted page table中尋找，看看裡面已有的physical frame對應的virtual page是不是跟現在需要資料的process所對應的virtual page一樣
如果一樣，就可以直接拿來用；不一樣則page fault
:::
### Two-level Page Tables
![](https://i.imgur.com/MNysbwP.png)
:::info
本來一個page size是4KB，也就是12bit
那在32bit的定址能力中，就會剩下20bit用作page number
這裡將他平分，切成10bit、10bit
由第一個10bit形成第一層的page table，指向第二層的page table

* 第一層只有一個page table，包含$2^{10} = 1024$個entry
    其中每個entry又各自對應到一個第二層的page table
* 第二層有1024個page table（因為第一層page table有1024個entry）
    又因為第二層可以用10bit，所以每個page table又有1024個entry
* 這裡令第二層page table中的每個entry對應到一個page
    相當於切成好幾個page table而每個都代表一個page
    所以這個例子中的two-level page table也是paged page table
:::
:::info
優點：
可以跟virtual memory system結合，好管理（可以放在physical memory或disk）
也不用擔心page table太大，占掉過多physical memory
:::
:::warning
可以與資料結構中的**tree**比較
第一層page table視為一個node，第二層的page table都是這個node的subtree
每個subtree下又會有1024個subnode，這些subnode就是frame
:::
## Impact of Paging – More Memory Access!
![](https://i.imgur.com/SKbRhp7.png)
```
圖中可以發現，因為採用virtual memory system
所以需要存取page table，變相要多存取一次physical memory
由於memory速度比起CPU慢很多，這樣會拖慢速度
所以創造了一個"類似cache"的東西，叫做Translation Lookaside Buffer(TLB)
```
### Making Address Translation Practical
:::warning
TLB可以視為page table的cache
:::
![](https://i.imgur.com/T71zCAU.png)
```
如果CPU要進行virtual memory accesss
他就會先去TLB看看有沒有用過
運氣好，有用過，就可以從TLB直接得到位址，直接存去cache或physical memory
如果沒有用過（TLB miss），就要去physical memory查詢page table
```
![](https://i.imgur.com/G2JuGi3.png)
```
過去：
CPU產生virtual address之後，只能去看page table，再去找資料
```
:::info
現在：
經過一次查詢page table去找physical memory或disk的資料後
就把查詢結果存到TLB中

之後如果CPU又產生了virtual address
會率先去找TLB有沒有過去用過的紀錄，如果有，就可以直接得到physical address
如果沒有，才要去page table查詢
好處是：有在TLB的話，可以省去查詢一次page table的時間
:::
:::danger
main concept：
跟cache一樣，都是利用**locality**的性質
:::
#### Translation Lookaside Buffer
通常，採用RISC的CPU都會有一個MMU（memory management unit）專門做記憶體管理，其中會包含TLB、page table lookup等相關事項


下面講述TLB的特質：
1. size不大
2. 可以採用fully associative、set associative、direct mapped
3. miss發生時，可能由硬體或軟體(OS)幫忙處理
#### TLB Hit or Miss
* TLB hit on read
    CPU要read的時候TLB hit：直接存取位址＆資料
* TLB hit on write
    CPU要write的時候TLB hit：存取位址＆資料，並將dirty bit設為1
    （因為日後若發生swap，才知道要把這個page寫回memory或disk）
* TLB miss
    可能有兩種狀況：
    1. 只是TLB不夠大所以放不下，東西還有在page table中：只要透過硬體或OS幫忙處理即可>>根據page table中的資訊，存取physical memory後順便放入TLB
    2. ★☆東西根本不在page table中（也發生了page fault）：只能靠OS幫忙處理>>把合適的page從disk找出，load到frame上☆★
## Page Fault Handler
1. 從disk中的swap區，找出所需資料
2. 從memory中，挑出要replacement的frame
    （如果dirty bit = 1還必須要同時寫回disk）
3. 從disk拿出page，放入frame（還要記得更新page table）
## TLB and Cache運作流程
下圖展示了完整的TLB、cache access的過程
![](https://i.imgur.com/n55ryO7.png)
下圖是TLB、cache運作的流程圖
可以發現，最糟的狀況是TLB、page table、cache全都miss
![](https://i.imgur.com/dar3QUX.png)
下表是TLB、page table、cache的各種狀況
![](https://i.imgur.com/lkZ5uej.png)
下面三種不可能發生，因為：
1. 不可能TLB hit結果不在page table中；都會是先在page table中，才存到TLB中
2. 不可能TLB miss、page table也miss，結果cache hit；因為前兩者miss代表東西不在memory中，不在memory怎麼可能會在cache中呢

## Summary
記憶體只要大，就慢；可是快，很貴，為了成本只能小
想要又大、又快、又便宜的記憶體，就要採用**memory hierarchy**
因為程式執行時，具有locality的特性，所以可以cache、TLB輔助