深入理解計算機組成原理-存儲于I/O
在 SRAM 里面,一個比特的數據,需要 6~8 個晶體管。所以 SRAM 的存儲密度不高。同樣的物理空間下,能夠存儲的數據有限。不過,因為 SRAM 的電路簡單,所以訪問速度非常快。
在 CPU 里,通常會有 L1、L2、L3 這樣三層高速緩存,每個 CPU 核心都有一塊屬于自己的 L1 高速緩存,通常分成指令緩存和數據緩存,分開存放 CPU 使用的指令和數據
L1 的 Cache 往往就嵌在 CPU 核心的內部;
L2 的 Cache 同樣是每個 CPU 核心都有的,不過它往往不在 CPU 核心的內部。所以,L2 Cache 的訪問速度會比 L1 稍微慢一些。而 L3 Cache,則通常是多個 CPU 核心共用的,尺寸會更大一些,訪問速度自然也就更慢一些。
DRAM 被稱為“動態”存儲器,是因為 DRAM 需要靠不斷地“刷新”,才能保持數據被存儲起來。DRAM 的一個比特,只需要一個晶體管和一個電容就能存儲。所以,DRAM 在同樣的物理空間下,能夠存儲的數據也就更多,也就是存儲的“密度”更大。但是,因為數據是存儲在電容里的,電容會不斷漏電,所以需要定時刷新充電,才能保持數據不丟失。DRAM 的數據訪問電路和刷新電路都比 SRAM 更復雜,所以訪問延時也就更長。


直接映射 Cache(Direct Mapped Cache直接映射
現代 CPU 已經很少使用直接映射 Cache 了,通常用的是組相連 Cache(set associative cache)
一個內存的訪問地址,最終包括高位代表的組標記、低位代表的索引,以及在對應的 Data Block 中定位對應字的位置偏移量

volatile 關鍵字究竟代表它會確保我們對于這個變量的讀取和寫入,都一定會同步到主內存里,而不是從 Cache 里面讀取

緩存同步 L1 L2 多核
總線嗅探機制和 MESI 協議
M:代表已修改(Modified)E:代表獨占(Exclusive)S:代表共享(Shared)I:代表已失效(Invalidated)
這個策略,本質上就是把所有的讀寫請求都通過總線(Bus)廣播給所有的 CPU 核心
總線本身就是一個特別適合廣播進行數據傳輸的機制,所以總線嗅探這個辦法也是我們日常使用的 Intel CPU 進行緩存一致性處理的解決方案
映射表。
我們的內存需要被分成固定大小的頁(Page),然后再通過虛擬內存地址(Virtual Address)到物理內存地址(Physical Address)的地址轉換(Address Translation),才能到達實際存放數據的物理內存位置。而我們的程序看到的內存地址,都是虛擬內存地址。
TLB,全稱是地址變換高速緩沖
我們通過頁表這個數據結構來處理。為了節約頁表的內存存儲空間,我們會使用多級頁表數據結構
不過,多級頁表雖然節約了我們的存儲空間,但是卻帶來了時間上的開銷,變成了一個“以時間換空間”的策略。原本我們進行一次地址轉換,只需要訪問一次內存就能找到物理頁號,算出物理內存地址。但是用了 4 級頁表,我們就需要訪問 4 次內存,才能找到物理頁號。
為了節約頁表所需要的內存空間,我們采用了多級頁表這樣一個數據結構。但是,多級頁表雖然節省空間了,卻要花費更多的時間去多次訪問內存。于是,我們在實際進行地址轉換的 MMU 旁邊放上了 TLB 這個用于地址轉換的緩存。TLB 也像 CPU Cache 一樣,分成指令和數據部分,也可以進行 L1、L2 這樣的分層。

我們現在常用的硬盤有兩種。一種是 HDD 硬盤,也就是我們常說的機械硬盤。另一種是 SSD 硬盤,一般也被叫作固態硬盤?,F在的 HDD 硬盤,用的是 SATA 3.0 的接口。而 SSD 硬盤呢,通常會用兩種接口,一部分用的也是 SATA 3.0 的接口;另一部分呢,用的是 PCI Express 的接口?,F在我們常用的 SATA 3.0 的接口,帶寬是 6Gb/s。這里的“b”是比特。這個帶寬相當于每秒可以傳輸 768MB 的數據。而我們日常用的 HDD 硬盤的數據傳輸率,差不多在 200MB/s 左右。
SSD 硬盤能夠更快,所以我們可以換用 PCI Express 的接口。我自己電腦的系統盤就是一塊使用了 PCI Express 的三星 SSD 硬盤。它的數據傳輸率,在讀取的時候就能做到 2GB/s 左右,差不多是 HDD 硬盤的 10 倍,而在寫入的時候也能有 1.2GB/s
順序讀寫和隨機讀寫
隨機讀寫的時候,數據傳輸率也只能到 40MB/s 左右,是順序讀寫情況下的幾十分之一。
在 top 命令的輸出結果里面,有一行是以 %CPU 開頭的。這一行里,有一個叫作 wa 的指標,這個指標就代表著 iowait,也就是 CPU 等待 IO 完成操作花費的時間占 CPU 的百分比。下一次,當你自己的服務器遇到性能瓶頸,load 很大的時候,你就可以通過 top 看一看這個指標。
我們看到,即使是用上了 PCI Express 接口的 SSD 硬盤,IOPS 也就是在 2 萬左右。而我們的 CPU 的主頻通常在 2GHz 以上,也就是每秒可以做 20 億次操作。
這里的 tps 指標,其實就對應著我們上面所說的硬盤的 IOPS 性能。而 kB_read/s 和 kB_wrtn/s 指標,就對應著我們的數據傳輸率的指標。
通過 iotop 這個命令,你可以看到具體是哪一個進程實際占用了大量 I/O,那么你就可以有的放矢,去優化對應的程序了
每秒鐘能夠進行輸入輸出的操作次數,也就是 IOPS 這個核心性能指標。
如果隨機在整個硬盤上找一個數據,需要 8-14 ms。我們的硬盤是機械結構的,只有一個電機轉軸,也只有一個懸臂,所以我們沒有辦法并行地去定位或者讀取數據。那一塊 7200 轉的硬盤,我們一秒鐘隨機的 IO 訪問次數,也就是1s / 8 ms = 125 IOPS 或者 1s / 14ms = 70 IOPS

SSD 硬盤,我們也可以先簡單地認為,它是由一個電容加上一個電壓計組合在一起,
記錄了一個或者多個比特。
我們上面說的 SLC 的芯片,可以擦除的次數大概在 10 萬次,MLC 就在 1 萬次左右而 TLC 和 QLC 就只在幾千次了
為什么ssd斷電后不會丟數據
作者回復: 現在大家用的SSD的存儲硬件都是NAND Flash。實現原理和通過改變電壓,讓電子進入絕緣層的浮柵(Floating Gate)內。斷電之后,電子仍然在FG里面。但是如果長時間不通電,比如幾年,仍然可能會丟數據。所以換句話說,SSD的確也不適合作為冷數據備份。
https://www.bilibili.com/video/av61437877


當 SSD 硬盤的存儲空間被占用得越來越多,每一次寫入新數據,我們都可能沒有足夠的空白。我們可能不得不去進行垃圾回收,合并一些塊里面的頁,然后再擦除掉一些頁,才能勻出一些空間來。這個時候,從應用層或者操作系統層面來看,我們可能只是寫入了一個 4KB 或者 4MB 的數據。但是,實際通過 FTL 之后,我們可能要去搬運 8MB、16MB 甚至更多的數據。我們通過“實際的閃存寫入的數據量 / 系統通過 FTL 寫入的數據量 = 寫入放大”,可以得到,寫入放大的倍數越多,意味著實際的 SSD 性能也就越差,會遠遠比不上實際 SSD 硬盤標稱的指標。
嘗試不停地提升 I/O 設備的速度。把 HDD 硬盤換成 SSD 硬盤,我們仍然覺得不夠快;用 PCI Express 接口的 SSD 硬盤替代 SATA 接口的 SSD 硬盤,我們還是覺得不夠快,所以,現在就有了傲騰(Optane)這樣的技術
但是,無論 I/O 速度如何提升,比起 CPU,總還是太慢。SSD 硬盤的 IOPS 可以到 2 萬、4 萬,但是我們 CPU 的主頻有 2GHz 以上,也就意味著每秒會有 20 億次的操作。如果我們對于 I/O 的操作,都是由 CPU 發出對應的指令,然后等待 I/O 設備完成操作之后返回,那 CPU 有大量的時間其實都是在等待 I/O 設備完成操作。但是,這個 CPU 的等待,在很多時候,其實并沒有太多的實際意義。我們對于 I/O 設備的大量操作,其實都只是把內存里面的數據,傳輸到 I/O 設備而已。在這種情況下,其實 CPU 只是在傻等而已。特別是當傳輸的數據量比較大的時候,比如進行大文件復制,如果所有數據都要經過 CPU,實在是有點兒太浪費時間了。因此,計算機工程師們,就發明了 DMA 技術,
也就是直接內存訪問(Direct Memory Access)技術,來減少 CPU 等待的時間
Kafka 是一個用來處理實時數據的管道,我們常常用它來做一個消息隊列,或者用來收集和落地海量的日志。作為一個處理實時數據和日志的管道,瓶頸自然也在 I/O 層面。Kafka 里面會有兩種常見的海量數據傳輸的情況。一種是從網絡中接收上游的數據,然后需要落地到本地的磁盤上,確保數據不丟失。另一種情況呢,則是從本地磁盤上讀取出來,通過網絡發送出去。

Kafka 做的事情就是,把這個數據搬運的次數,從上面的四次,變成了兩次,并且只有 DMA 來進行數據搬運,而不需要 CPU
fileChannel.transferTo(position, count, socketChannel);
Kafka 的代碼調用了 Java NIO 庫,具體是 FileChannel 里面的 transferTo 方法。我們的數據并沒有讀到中間的應用內存里面,而是直接通過 Channel,寫入到對應的網絡設備里。并且,對于 Socket 的操作,也不是寫入到 Socket 的 Buffer 里面,而是直接根據描述符(Descriptor)寫入到網卡的緩沖區里面。于是,在這個過程之中,我們只進行了兩次數據傳輸。

單筆特翻轉發生的概率是0.01%,那么兩個比特都翻轉概率就是0.000001%。 要解決這個問題成本會進一步大幅度上升,就沒有必要在硬件層面這么干了。


2022-09-05 08:39:04
2024-11-01 08:57:07




