Wildsky

ws://wildsky.cc

耿 . Front-end Developer . Firefox Add-on Developer

作業系統 Ch2-2 - storage
Wildsky

這個章節主要講電腦儲存資料的相關架構,並討論背後需要在意的問題。 往後延伸到「不同的程式共用相同資源時,OS 在權限管理上的設計」。

儲存裝置最在意的三件事

  • Speed
  • Cost
  • volatile: 斷電後資料是否會遺失

越快就越貴。如果想要一台 C/P 值高的電腦,就會需要有階層的架構。

儲存裝置的階層

  1. register
  2. cache
  3. memory
  4. disk
  5. 光碟
  6. 磁帶

現代還是有在用磁帶,因為比較穩,不會因為摔到或碰到水資料就整組壞光光了。

上述的 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 搜尋結果的例子, 但我自己是覺得搜尋結果的不同應該和一致性的關係較小,和個人化的關係較大。

話說回來,要怎麼讓每個程式,每台電腦都能有 看似相同 的資料呢?就是要透過 protection 了。

Protection

這裡指的不是對網路攻擊之類的 protection,比較像是各程式間對資源的 權限控管。 這邊有兩個例子:

  1. 某程式 crash 時,應該要只會看到 A 程式的錯誤訊息,不會整台電腦掛掉。
  2. 某程式能改動的只有自己的 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 能管理。
    • 所以在 call 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

  • 要保護下面兩種東西:
    1. interrupt vector & interrupt service routine
    2. 從其他程式來的資料存取
  • 保護 2. 的實際作法:
    • 把程式限制在一段空間中,超過就不准你亂動。
    • 硬體支援: 用兩個 register 記錄可操作的範圍
    • base register
    • limit register

當程式要去 access memory 時就會跑這個流程:

  1. 先 load base register,看 address 有無大於開始位置。
    • 若小於就丟一個 trap(因為 trigger by software)
  2. 檢查 base + limit,看 address 有無小於結束位址。
  3. 通過前面兩個判定後,才會把指令丟去 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 不是讀出來)

ref:

Geng-Zhi Fann © 2018

Powered by Hugo & Kiss.