這個章節主要講電腦儲存資料的相關架構,並討論背後需要在意的問題。往後延伸到「不同的程式共用相同資源時,OS 在權限管理上 作業系統 的設計」。
儲存裝置最在意的三件事
- Speed
- Cost
- volatile:斷電後資料是否會遺失
越快就越貴。如果想要一台 C/P 值高的電腦,就會需要有階層的架構。
儲存裝置的階層
- register
- cache
- memory
- disk
- 光碟
- 磁帶
一到六排序是由快到慢,由貴到便宜。現代還是有在用磁帶,因為比較穩,不會因為摔到或碰到水資料就整組壞光光了。
上述的 1,2,3 屬於 main memory;4,5,6 則是 secondary storage。前者是 volatile,後者都非 volatile。
下面分別列各自的特性:
Main Memory
- CPU 可直接 access 的儲存區塊(速度快)。
- 比較貴。
- volatile
- a.k.a RAM
- 讀取任何位置的資料,時間都是一樣的。
- 每次讀取速度都一致。
- Disk 與之相反,會因為讀取位置不同而有不同的速度(後述)。
Secondary Storage
- 速度較慢:CPU 不可直接讀,要讀要先搬進 main memory。
- 空間較大
- 比較便宜
- non-volatile
磁碟的讀取速度
因為是機械式的,有磁頭。
所以 資料位置和磁頭間的距離 就是造成 access 時間不同的主因。
* access time = transfer time + position time
* transfer time = data_size / transfer rate
* position time (random access time) = seek time + rotational latency
- seek time: 磁頭從當前位置去找資料位置的時間,可能很快也可能很慢。(硬碟說的 7200 轉、3600 轉,就是和這個有關)
- 所以當資料量越大(都在連續位置上),seek time 對 access 的時間就越不重要。
那階層要如何讓電腦的資料存取更快速呢?就要透過 caching。
快取機制 Caching
將資料暫時從下層複製到上層,目的是增加 access 的速度。
-
所有資料最終都儲存在空間最大但速度最慢的磁碟。
-
所以為了快一點,就會把資料往上層 copy。
-
實際運作:
-
CPU 第一次 access 資料時,會由上往下一層一層看有無 cache,沒有就往下找,找到有為止。
-
找到後就會複製一份到上層。
-
所以 第一次會比沒有 cache 的系統慢,因為除了要一層層找之外,還要複製資料。
-
但第二次之後都會飛快。
-
因此,有的系統就不會做 caching。
舉例,每次都要處理大量資料的話,做 cache 就沒有意義,重讀資料還比較有效率。
有了複製就會出現 A 改 B 沒改的狀況,也就是不一致性的問題。
不一致性 coherency & consistency
- 因為修改一定從最上層改,所以上下層可能資料不同。(不過給使用者看的一樣就好,所以其實也還好(?))
- 那不一致性困擾在哪?
- 單一程式:依照階層去做 Copy 就好,一個人時問題不大。
- 多個程式:要改同個資料的時候,不同程式改資料的時間可能不同⋯⋯
- 分散式系統:不同電腦要用同份資料⋯⋯ 大家還要資料相同⋯⋯ (還有網路問題⋯⋯)
- 解決的原則就是:要製造出每個程式、每台電腦使用到的資料好像都是一致的假象。
有的系統會為了效率放棄一致性。
這邊周老師舉了 Google 搜尋結果的例子,但我自己是覺得搜尋結果的不同應該和一致性的關係較小,和個人化的關係較大。不過 Google 這個例子也有相關,忽略個人化的話各區的搜尋結果應該也還是會有差異,但我沒有證據,就只是推測就是了。
話說回來,要怎麼讓每個程式,每台電腦都能有 看似相同 的資料呢?就是要透過 protection 了。
Protection
這裡指的不是對網路攻擊之類的 protection,比較像是各程式間對資源的 權限控管。這邊有兩個例子:
- 某程式 crash 時,應該要只會看到 A 程式的錯誤訊息,不會整台電腦掛掉。
- 某程式能改動的只有自己的 memory,要改動其他人的資料就一定要透過 OS 或 controller 才可以(就是要經過上層同意)。
dual-mode
OS 要能夠區分一個 instruction 是來自 user program 還是 OS。
硬體 會提供至少兩種 mode 來支援 dual mode 的建立。
- User mode : user program 的行為來的。
- Monitor mode (kernal mode): OS 的行為來的。
如何區分?
-
硬體用一個 bit 去記錄是那個 mode(設為 isUserMode)。
-
平常 isUserMode = 1。
-
當 call 了 interrupt 就會 flip,變成 isUserMode = 0。
-
等 OS 跑完 return 時就會再 flip,變回 isUserMode = 1。
-
實作
-
硬體在設計時就會有 privileged instructions 在其中。
-
只在 monitor mode 執行(不然就會被擋住,拋出 error 給 OS 處理)
-
User program 就需要 call system call 來做想做的事,讓 OS 能管理。
-
-
所以在呼叫 system call 時,一定會有下面兩件事發生:
- 一開始跑時會先 flip isUserMode 的這個 bit。
- 跑完後再 flip 回來。
-
藉由這個 dual-mode 的概念就可以延伸出下面三方面的 protection
- I/O protection
- Memory protection
- CPU protection
講電腦也就都圍繞在這三件事上而已。下面來分別介紹。
I/O Protection
- 硬體支援: 所有的 I/O 都是 privileged instructions。
- 因為都是共用的。
- 只保護 I/O 是不夠的,如果沒保護 memory,就可能被竄改 interrupt vector,讓 OS 執行不該執行的程式。
Memory Protection
- 要保護下面兩種東西:
- interrupt vector & interrupt service routine
- 從其他程式來的資料存取
- 保護 2. 的實際作法:
- 把程式限制在一段空間中,超過就不准你亂動。
- 硬體支援: 用兩個 register 記錄可操作的範圍
- base register
- limit register
當程式要去 access memory 時就會跑這個流程:
- 先 load base register,看 address 有無大於開始位置。
- 若小於就丟一個 trap(因為 trigger by software)
- 檢查 base + limit,看 address 有無小於結束位址。
- 通過前面兩個判定後,才會把指令丟去 memory 的 bus,讓 memory controller 去做 data access。
所以 base register & limit register 這類用於檢查的 register 都是 privileged instructions。
CPU Protection
- 避免一隻程式一直霸佔 CPU,必須要能夠隨時把 CPU 使用權拿回來。
- 如何施行?
- 利用 Time sharing 的概念。
- 硬體支援: Timer
- 會一直計時,時間到就丟 interrupt,執行 OS 的 scheduler,讓他決定繼續執行 or not。
所以 load-time 也是個 privileged instruction。(這邊的 load 是把值 load 到 timer 不是讀出來)
參考連結
關於 作業系統 的相關筆記,可以見這裡: http://blog.wildsky.cc/tags/os/