<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么 CPU 訪問硬盤很慢

          共 3983字,需瀏覽 8分鐘

           ·

          2020-08-14 14:57

          為什么這么設(shè)計(jì)(Why’s THE Design)是一系列關(guān)于計(jì)算機(jī)領(lǐng)域中程序設(shè)計(jì)決策的文章,我們?cè)谶@個(gè)系列的每一篇文章中都會(huì)提出一個(gè)具體的問題并從不同的角度討論這種設(shè)計(jì)的優(yōu)缺點(diǎn)、對(duì)具體實(shí)現(xiàn)造成的影響。如果你有想要了解的問題,可以在文章下面留言。

          機(jī)械硬盤(Hard Disk Drive、HDD)和固態(tài)硬盤(Solid State Drive、SSD)是兩種最常見的硬盤,作為計(jì)算機(jī)的外部存儲(chǔ),CPU 想要訪問它們存儲(chǔ)的數(shù)據(jù)需要很長時(shí)間,如下表所示,在 SSD 中隨機(jī)訪問 4KB 數(shù)據(jù)所需要的時(shí)間是訪問主存的 1,500 倍,機(jī)械磁盤的尋道時(shí)間是訪問主存的 100,000 倍:

          WorkLatency
          L1 cache reference0.5 ns
          Branch mispredict5 ? ns
          L2 cache reference7 ? ns
          Mutex lock/unlock25 ? ns
          Main memory reference100 ? ns
          Compress 1K bytes with Zippy3,000 ? ns
          Send 1K bytes over 1 Gbps network10,000 ? ns
          Read 4K randomly from SSD*150,000 ? ns
          Read 1 MB sequentially from memory250,000 ? ns
          Round trip within same datacenter500,000 ? ns
          Read 1 MB sequentially from SSD*1,000,000 ? ns
          Disk seek10,000,000 ? ns
          Read 1 MB sequentially from disk20,000,000 ? ns
          Send packet CA->Netherlands->CA150,000,000 ? ns

          表 1 - 2012 年延遲數(shù)字對(duì)比[^1]

          雖然磁盤的尋道時(shí)間只需要 10ms,但是在 CPU 看來已經(jīng)是非常長的時(shí)間了,當(dāng)我們將上述的時(shí)間等比例放大后,就能直觀地感受到它們的性能差異。如果 CPU 訪問 L1 緩存需要 1 秒,那么訪問主存需要 3 分鐘、從 SSD 中隨機(jī)讀取數(shù)據(jù)需要 3.4 天、磁盤尋道需要 2 個(gè)月,網(wǎng)絡(luò)傳輸可能需要 1 年多的時(shí)間。

          在計(jì)算機(jī)體系結(jié)構(gòu)中,硬盤屬于一種常見的輸入輸出設(shè)備,操作系統(tǒng)在啟動(dòng)時(shí)不一定需要硬盤,它既可以通過硬盤啟動(dòng),也可以通過網(wǎng)絡(luò)設(shè)備或者外部設(shè)備啟動(dòng),所以硬盤不是計(jì)算機(jī)運(yùn)行的必要條件。

          von-neumann-architecture.svg

          圖 1 - 輸入輸出設(shè)備

          作為一種外部的輸入輸出設(shè)備,與 CPU 緩存和內(nèi)存相比,硬盤極慢的讀取和寫入速度就顯得比較合理了,然而幾千倍甚至幾十萬倍的速度差異也確實(shí)讓人很難想象或者接受,在這篇文章中,我們會(huì)分析為什么 CPU 訪問硬盤的速度非常慢:

          • CPU 訪問硬盤數(shù)據(jù)的過程比較復(fù)雜,它會(huì)先通過 I/O 操作將磁盤中的數(shù)據(jù)讀入內(nèi)存,再訪問內(nèi)存的數(shù)據(jù);
          • 機(jī)械硬盤在訪問磁盤中的數(shù)據(jù)依賴的是機(jī)械結(jié)構(gòu),需要移動(dòng)磁盤中的機(jī)械臂;

          I/O 操作

          CPU 想要訪問磁盤中的數(shù)據(jù)一定要先通過 I/O 操作將磁盤中的數(shù)據(jù)讀入到內(nèi)存中,再訪問存儲(chǔ)在內(nèi)存中的數(shù)據(jù)。計(jì)算機(jī)中包含三種比較常見的 I/O 操作[^2] — 編程 I/O(Programmed I/O)、中斷驅(qū)動(dòng) I/O(Interrupt-driven I/O)和直接內(nèi)存訪問(Direct Memory Access),我們接下來將依次介紹上述的這幾種操作[^3]:

          io-operation

          圖 2 - 常見 I/O 操作

          執(zhí)行 I/O 操作最簡單的形式就是使用編程 I/O,使用編程 I/O 時(shí),CPU 會(huì)負(fù)責(zé)全部的工作,如果我們想要在屏幕上輸出 Hello World,CPU 每次都會(huì)向 I/O 設(shè)備中寫入一個(gè)新字符,寫入后會(huì)輪詢?cè)O(shè)備的狀態(tài)等待它完成工作后寫入新的字符。這種方式雖然簡單,但是它會(huì)占用全部的 CPU 資源,在某些復(fù)雜的系統(tǒng)中會(huì)造成計(jì)算資源的嚴(yán)重浪費(fèi)。

          中斷驅(qū)動(dòng) I/O 是執(zhí)行 I/O 操作的一種更高效方式,在編程 I/O 中,CPU 會(huì)主動(dòng)獲取設(shè)備的狀態(tài)并等待設(shè)備閑置,但是如果使用了中斷驅(qū)動(dòng) I/O,設(shè)備會(huì)在閑置時(shí)主動(dòng)發(fā)起中斷暫停當(dāng)前進(jìn)程并保存上下文,而操作系統(tǒng)會(huì)執(zhí)行 I/O 設(shè)備的中斷處理程序:

          • 如果當(dāng)前不包含待打印的字符,停止中斷處理程序并恢復(fù)暫停的進(jìn)程;
          • 如果當(dāng)前包含待打印的字符,將下一個(gè)字符拷貝到設(shè)備中并恢復(fù)暫停的進(jìn)程;

          使用中斷驅(qū)動(dòng) I/O 可以在設(shè)備繁忙時(shí),讓 CPU 能夠處理其它任務(wù),盡可能地提高 CPU 的利用率,不再浪費(fèi)珍貴的計(jì)算資源。與編程 I/O 相比,中斷驅(qū)動(dòng) I/O 將一部分工作交給了 I/O 設(shè)備,所以能夠提高資源的利用率。

          直接內(nèi)存訪問會(huì)利用 DMA 控制器來執(zhí)行 I/O 操作,中斷驅(qū)動(dòng) I/O 需要為每個(gè)字符觸發(fā)操作系統(tǒng)中斷,這會(huì)消耗一定的 CPU 時(shí)間。當(dāng)我們使用 DMA 控制器時(shí),CPU 會(huì)一次將緩沖區(qū)中的數(shù)據(jù)全部讀到 DMA 控制器中,DMA 控制器會(huì)負(fù)責(zé)將數(shù)據(jù)按字符寫入 I/O 設(shè)備:

          dma-controller

          圖 3 - DMA I/O

          雖然 DMA 控制器可以解放 CPU 并減少中斷次數(shù),但是它的執(zhí)行速度與 CPU 相比卻很慢,如果 DMA 控制器不能快速驅(qū)動(dòng) I/O 設(shè)備,CPU 可能就會(huì)等待 DMA 控制器觸發(fā)中斷,在這種情況下,中斷驅(qū)動(dòng) I/O 或者編程 I/O 可以提供更快的訪問速度。

          在默認(rèn)情況下,我們都會(huì)使用 DMA 控制器來執(zhí)行 I/O 任務(wù),不過編程 I/O 和中斷驅(qū)動(dòng) I/O 也不是不能接受的選項(xiàng)。當(dāng) CPU 經(jīng)常需要等待 DMA 控制器執(zhí)行 I/O 任務(wù)時(shí),使用中斷驅(qū)動(dòng) I/O 甚至輪詢的編程 I/O 都可以得到更高的吞吐量,然而無論使用哪種方式,I/O 都是程序中比較耗時(shí)的復(fù)雜操作。

          機(jī)械硬盤

          機(jī)械硬盤(Hard Disk Drive、HDD)是一種基于電子的、非易失的機(jī)械數(shù)據(jù)存儲(chǔ)設(shè)備,它使用磁性存儲(chǔ)器存儲(chǔ)并查找磁盤上的數(shù)據(jù),在讀取和寫入數(shù)據(jù)的過程中,硬盤機(jī)械臂連接的磁頭會(huì)讀寫磁盤表面的位[^8]。

          正是因?yàn)榇疟P具有比較復(fù)雜的機(jī)械結(jié)構(gòu),所以磁盤的讀取和寫入都要花費(fèi)很多時(shí)間,數(shù)據(jù)庫的讀寫性能也基本都依賴于磁盤的性能,如果我們?cè)谑褂脵C(jī)械硬盤的數(shù)據(jù)庫中隨機(jī)查詢一條數(shù)據(jù),這可能會(huì)觸發(fā)磁盤的隨機(jī) I/O,然而將數(shù)據(jù)從磁盤讀取到內(nèi)存中所需要的成本是非常大的,普通磁盤(非 SSD)加載數(shù)據(jù)需要經(jīng)過隊(duì)列、尋道、旋轉(zhuǎn)以及傳輸?shù)倪@些過程,大概要花費(fèi) 10ms 左右的時(shí)間。

          disk-random-io

          圖 4 - 磁盤的隨機(jī) I/O

          我們?cè)诠浪銛?shù)據(jù)庫的查詢時(shí)可以使用 10ms 這個(gè)數(shù)量級(jí)對(duì)隨機(jī) I/O 占用的時(shí)間進(jìn)行估算,這里想要說的是隨機(jī) I/O 對(duì)于數(shù)據(jù)庫的查詢性能影響會(huì)非常大,而順序讀取磁盤中的數(shù)據(jù)時(shí)速度可以達(dá)到 40MB/s,這兩者的性能差距有幾個(gè)數(shù)量級(jí),因此我們也應(yīng)該盡量減少隨機(jī) I/O 的次數(shù),這樣才能提高性能。

          固態(tài)硬盤(Solid State Drive、SSD)是一種以閃存作為持久存儲(chǔ)器的電腦存儲(chǔ)設(shè)備[^9]。與機(jī)械硬盤不同,固態(tài)硬盤中不包含任何的機(jī)械結(jié)構(gòu),我們使用它讀取或者存儲(chǔ)數(shù)據(jù)時(shí)不會(huì)使用到任何的機(jī)械結(jié)構(gòu),因?yàn)橐磺羞^程都是由電路完成的,所以 SSD 的讀寫速度比 HDD 快很多。

          hdd-ssd-price

          圖 5 - HDD 和 SSD 的價(jià)格

          機(jī)械硬盤和 SSD 從誕生后價(jià)格都在不斷降低,機(jī)械硬盤是今天數(shù)據(jù)中心使用的主要外部存儲(chǔ),大多數(shù)通用的商用服務(wù)器都會(huì)使用機(jī)械硬盤作為主要的外部存儲(chǔ),但是因?yàn)?SSD 的讀寫速度是機(jī)械硬盤的幾十倍,所以越來越多的服務(wù)器,尤其是數(shù)據(jù)庫都會(huì)使用 SSD 作為外部存儲(chǔ)。不過作為具有機(jī)械結(jié)構(gòu)的外部存儲(chǔ)設(shè)備,它雖然結(jié)構(gòu)非常成熟并且具有較大的容量,但是它在受到震動(dòng)時(shí)很容易受到外界的干擾。

          總結(jié)

          硬盤是計(jì)算機(jī)上的外部存儲(chǔ)設(shè)備,它可以持久存儲(chǔ)大量數(shù)據(jù),然而 CPU 無法直接訪問硬盤中的數(shù)據(jù),當(dāng)計(jì)算機(jī)啟動(dòng)時(shí)操作系統(tǒng)會(huì)將硬盤中的數(shù)據(jù)加載到內(nèi)存中以便 CPU 訪問,但是如果 CPU 要訪問的數(shù)據(jù)不在內(nèi)存中,那么我們需要花費(fèi)幾千倍甚至幾十萬倍的時(shí)間來讀取數(shù)據(jù),這主要是由以下兩個(gè)原因造成的:

          • CPU 需要通過 I/O 操作訪問外部存儲(chǔ)中的數(shù)據(jù),編程 I/O、中斷驅(qū)動(dòng) I/O 和 DMA 幾種方式都會(huì)帶來額外開銷并占用較多的 CPU 時(shí)間;
          • 機(jī)械硬盤會(huì)通過機(jī)械結(jié)構(gòu)訪問其中存儲(chǔ)的數(shù)據(jù),每一次硬盤的隨機(jī) I/O 都需要執(zhí)行隊(duì)列、尋道、旋轉(zhuǎn)和轉(zhuǎn)移數(shù)據(jù)幾個(gè)過程,大約需要消耗 10ms 的時(shí)間;

          正如我們?cè)谖恼轮刑岬降模脖P不是計(jì)算機(jī)運(yùn)行的必要硬件設(shè)備,計(jì)算機(jī)可以從磁盤、光盤等任意外部存儲(chǔ)設(shè)備中將啟動(dòng)所需要的數(shù)據(jù)加載到內(nèi)存中并正常啟動(dòng),不過硬盤已經(jīng)是今天最為常見的外部存儲(chǔ)設(shè)備了。到最后,我們還是來看一些比較開放的相關(guān)問題,有興趣的讀者可以仔細(xì)思考一下下面的問題:

          • 寫入到硬盤上的數(shù)據(jù)一定會(huì)被持久存儲(chǔ),不會(huì)丟失嗎?
          • 內(nèi)存中的數(shù)據(jù)為什么在斷電重啟之后就會(huì)被清空?


          推薦閱讀



          學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進(jìn)群」即可


          站長 polarisxu

          自己的原創(chuàng)文章

          不限于 Go 技術(shù)

          職場和創(chuàng)業(yè)經(jīng)驗(yàn)


          Go語言中文網(wǎng)

          每天為你

          分享 Go 知識(shí)

          Go愛好者值得關(guān)注


          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男女怕怕网站 | 久久水蜜桃 | 国内精品综合视频 | 免费看黄色小视频 | 欧美日本高清视频 |