15-磁盤驅動(生磁盤)

生磁盤驅動就是指CPU直接向磁盤控制器讀寫數據,不是通過文件系統操作磁盤,文件系統是對生磁盤驅動的進一步抽象
那麼磁盤驅動跟其他外設驅動一樣,仍然從硬件開始,如下圖所示

CPU通過PCI總線向磁盤控制器發讀寫指令,待讀寫的內容載入內存後,磁盤控制器再向CPU發中斷信號,CPU從內存中取數據。

使用磁盤首先從認識磁盤開始

磁盤整體上是一個柱形的結構。圓柱是由一個個盤面疊加起來的,每個盤面又內到外的圓環稱爲磁道,每個刺刀上又分成多個扇區。磁盤訪問的基本單位是扇區

磁盤讀寫的過程就是CPU向磁盤控制器發指令,磁盤控制器先驅動磁臂到目標磁道上,然後在磁道上旋轉到目標扇區,最後從目標扇區中讀寫內容,傳輸到內存。如下圖所示

也就是說CPU需要向磁盤控制器發送柱面、磁頭、扇區、內存的讀寫緩存位置。
柱面是指在圓柱的哪一個子圓柱上,磁頭指在哪一個盤面上。如下圖所示

向磁盤控制器out柱面、磁頭、扇區、緩衝區
畢竟向磁盤控制器寫柱面、磁頭、扇區這些指令很麻煩,程序員還要去找柱面、磁頭扇區這些信息。因此向上作一層抽象,程序員只用指定盤塊號(block),然後磁盤驅動由盤塊號計算出cyl(柱面)、head(磁頭)、sec(扇區)。過程如下

那麼盤塊號如何讓編址使得磁盤訪問比較快呢?
磁盤的訪問時間=寫入控制器時間+尋道時間(8-12ms)+旋轉時間(7000rpm:半周4ms)+傳輸時間(50M/s,約0.3s)
可以看出尋道時間佔大頭,尋道時間是指將磁臂移到目標磁道上,是一個機械運動,自然耗時較久。旋轉時間是指在同一個磁道上旋轉到目標扇區的時間。
由於我們實際的程序總是會連續讀寫多個盤塊,因此我們希望相鄰盤塊可以快速讀出,那麼將同一個磁道上的相鄰位置編址成邏輯上的盤塊號。磁盤驅動要做的事情是由盤塊號計算柱面、磁頭和扇區

盤塊號又是怎麼編址的呢:C*(Head*sectors)+H*sectors+S
C是指柱面號,head是指每個柱面上的磁頭個數,sector是指每個磁道上的扇區個數,H指位於縱向的第幾個磁頭上,S指位於磁道上的第幾個扇區上。
將上述公式%sectors即取餘操作就可以計算出扇區,再通過其他類似操作也可以計算出C和H。
如果我們每次讀寫的扇區個數越多,那麼讀寫速度也就越大,每次讀寫的扇區個數就是盤塊大小。而盤塊越大,每次產生的內存碎片也就越大,會導致空間利用率降低,如下圖所示。

因此盤塊的大小是在空間利用率和讀寫速度之間取得平衡。
由於現在的操作系統都支持多進程,每個進程都有一個盤塊號(block),那麼先處理那一個進程使得總得磁盤讀寫時間比較短,用戶等待時間也不長呢。那麼在磁盤驅動前面又要使用第二層抽象:請求隊列。即通過磁盤調度算法將不同進程的block放進請求隊列中,使得平均訪問延遲小。如下圖所示

下面就進一步探究磁盤調度算法

還是從最簡單的先來先服務(FCFS)模型先分析
FCFS是最直觀、公平的調度算法。但是FCFS模型會造成尋道過程中近的位置到遠的位置頻繁移動,我們希望每次訪問的磁盤儘量相鄰,這樣尋道時間短,平均延遲時間也就短。

下面看一個實例:磁盤開始位置=53(block號)
請求隊列=98,183,27,122,14,124,65,67

FCFS造成磁臂在較長的距離上反覆折騰,尋道時間過長
因此我們想到了短尋道時間優先算法(SSTF),類似於進程調度的短任務優先
這樣尋道儘可能在附近的位置進行。那麼跟短任務優先一樣,會出現飢餓問題
接着上面的實例,SSTF處理過程如下:

假如在處理183之前,不斷插入小於183盤塊進程,那麼183永遠得不到響應

進一步引出了SSTF+中途不回折(SCAN):即由起始位置先連續訪問到block小的位置,中間從小的位置依次訪問到block最大的位置,這樣每個請求都有處理的機會

這樣中間位置被掃描到了兩次,對兩邊不公平。


我們在實際操作系統中採用的是C-SCAN磁盤調度(電梯算法
即SCAN+直接移動到另一端:輛段請求都能快速處理
磁頭由開始位置移動到最小位置後,不原路折返,而是切換到最大位置。這樣每個位置只掃描一次,由保證了每次尋道都儘可能連續,且每個請求都能得到響應。如下所示

總結一下,生磁盤的使用過程:

.

後面還需要將生磁盤再向上抽象一層,加上文件系統就成用戶使用的熟磁盤了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章