Skip to content

Commit

Permalink
Refine wording
Browse files Browse the repository at this point in the history
  • Loading branch information
jserv committed Dec 6, 2023
1 parent 0b73693 commit 66ad620
Show file tree
Hide file tree
Showing 37 changed files with 157 additions and 157 deletions.
2 changes: 1 addition & 1 deletion commodity-hardware-today/ram-types/conclusions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
* 位址線的數量直接反映記憶體控制器、主機板(motherboard)、DRAM 模組、與 DRAM 晶片的成本
* 在讀取或寫入操作的結果有效之前得花上一段時間

接下來的章節將會深入更多存取 DRAM 記憶體的實際過程的細節。我們不會深入存取 SRAM 的細節,它通常是直接定址的。這是基於速度考量,並且因為 SRAM 記憶體受限於其大小。SRAM 目前被用於 CPU 快取並內建於晶片上(on-die),其連線較少、並且完全在 CPU 設計者的控制中。CPU 快取是我們將會在之後談及的主題,但我們所需知道的是,SRAM 記憶單元有著確切的最大速度,這取決於在 SRAM 上所花的努力。速度可以從略微慢於 CPU 核到慢於一或二個數量級。
接下來的章節將會深入更多存取 DRAM 記憶體的實際過程的細節。我們不會深入存取 SRAM 的細節,它通常是直接定址的。這是基於速度考量,並且因為 SRAM 記憶體受限於其容量。SRAM 目前被用於 CPU 快取並內建於晶片上(on-die),其連線較少、並且完全在 CPU 設計者的控制中。CPU 快取是我們將會在之後談及的主題,但我們所需知道的是,SRAM 記憶單元有著確切的最大速度,這取決於在 SRAM 上所花的努力。速度可以從略微慢於 CPU 核到慢於一或二個數量級。

4 changes: 2 additions & 2 deletions commodity-hardware-today/ram-types/dram-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

由記憶體控制器個別定址(address)記憶體位置是極為不切實際的:4GB 的 RAM 會需要 2<sup>32</sup> 條位址線。作為替代,位址會使用較小的一組位址線,編碼成二進位數值傳遞。以這種方式傳遞到 DRAM 晶片的位址必須先被解多工(demultiplex)。有 $$ N $$ 條位址線的解多工器(demultiplexer)將會有 2<sup>$$ N $$</sup> 條輸出線(output line)。這些輸出線能被用以選擇記憶單元。對於小容量的晶片而言,使用這種直接的方法是沒什麼大問題的。

但假如記憶單元的數量增加,這個方法就不再合適。一個 1Gbit[^6] 容量的晶片將會需要 30 條位址線以及 2<sup>30</sup> 選擇線(select line)。在不犧牲速度的前提下,解多工器的大小會隨著輸入線(input line)的數量以指數成長。用於 30 條位址線的解多工器需要大量的晶片空間,外加解多工器的(尺寸與時間)複雜度。更重要的是,同時在位址線上傳輸 30 個脈衝(impulse)比「只」傳輸 15 個脈衝還要難得多。只有少數的位址線能夠以長度完全相同或適當安排時間的方式排版。[^7]
但假如記憶單元的數量增加,這個方法就不再合適。一個 1Gbit[^6] 容量的晶片將會需要 30 條位址線以及 2<sup>30</sup> 選擇線(select line)。在不犧牲速度的前提下,解多工器的容量會隨著輸入線(input line)的數量以指數成長。用於 30 條位址線的解多工器需要大量的晶片空間,外加解多工器的(尺寸與時間)複雜度。更重要的是,同時在位址線上傳輸 30 個脈衝(impulse)比「只」傳輸 15 個脈衝還要難得多。只有少數的位址線能夠以長度完全相同或適當安排時間的方式排版。[^7]

<figure>
<img src="../../assets/figure-2.7.png" alt="圖 2.7:動態 RAM 示意圖">
<figcaption>圖 2.7:動態 RAM 示意圖</figcaption>
</figure>

圖 2.7 顯示了以極高階角度示意的 DRAM 晶片。DRAM 記憶單元被組織在列(row)與行(column)中。雖然它們可以全都排成一列,但 DRAM 晶片會因而需要一個龐大的解多工器。藉由陣列(array)的方式,便能夠以各為一半大小的一個解多工器與一個多工器達到這種目的。[^8]這從各方面來說都是個大大的節約。在這個例子中,位址線 $$ \mathbf{a_{0}} $$ 與 $$ \mathbf{a_{1}} $$ 透過*列位址選擇(row address selection)*($$ \overline{\text{RAS}} $$)[^9]解多工器選擇一整列記憶單元的位址線。在讀取時,所有記憶單元的內容都能夠被*行位址選擇(column address selection)*多工器(multiplexer)($$ \overline{\text{CAS}} $$)取得。基於位址線 $$ \mathbf{a_{2}} $$ 與 $$ \mathbf{a_{3}} $$,其中一行的內容便能夠提供給 DRAM 晶片的資料針腳(pin)。這會在許多 DRAM 晶片上平行地發生多次,以產生對應於資料匯流排寬度的所有位元。
圖 2.7 顯示了以極高階角度示意的 DRAM 晶片。DRAM 記憶單元被組織在列(row)與行(column)中。雖然它們可以全都排成一列,但 DRAM 晶片會因而需要一個龐大的解多工器。藉由陣列(array)的方式,便能夠以各為一半容量的一個解多工器與一個多工器達到這種目的。[^8]這從各方面來說都是個大大的節約。在這個例子中,位址線 $$ \mathbf{a_{0}} $$ 與 $$ \mathbf{a_{1}} $$ 透過*列位址選擇(row address selection)*($$ \overline{\text{RAS}} $$)[^9]解多工器選擇一整列記憶單元的位址線。在讀取時,所有記憶單元的內容都能夠被*行位址選擇(column address selection)*多工器(multiplexer)($$ \overline{\text{CAS}} $$)取得。基於位址線 $$ \mathbf{a_{2}} $$ 與 $$ \mathbf{a_{3}} $$,其中一行的內容便能夠提供給 DRAM 晶片的資料針腳(pin)。這會在許多 DRAM 晶片上平行地發生多次,以產生對應於資料匯流排寬度的所有位元。

對於寫入操作,新的記憶單元的值會被置於資料匯流排中,然後 ── 當記憶單元藉由 $$ \overline{\text{RAS}} $$$$ \overline{\text{CAS}} $$ 選取時 ── 儲存到資料單元中。相當直觀的設計。這實際上有著顯然地更多的困難。需要規範發出訊號之後,在資料能夠由資料匯流排讀取之前有多少延遲。如同上節所述,電容無法立即充放電。來自於記憶單元的訊號太微弱了,以致於它非得被放大(amplify)不可。對於寫入操作,必須指定設置完 $$ \overline{\text{RAS}} $$$$ \overline{\text{CAS}} $$ 之後,資料必須在匯流排維持多久,才能夠成功地在記憶單元中儲存新值(再提醒一次,電容不會立即被充放電)。這些時間常數(constant)對於 DRAM 晶片的效能而言是至關重要的。我們將會在下一節討論這些。

Expand Down
2 changes: 1 addition & 1 deletion commodity-hardware-today/ram-types/dynamic-ram.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $$

不像靜態 RAM 能夠在字組存取線路的電位提高時立即取得輸出結果,它會花費一些時間以讓電容被充分放電。這個延遲嚴重地限制了 DRAM 能夠達到的速度。

簡單的方法也有其優點。最主要的優點是大小。比起一個 SRAM 的記憶單元,一個 DRAM 的記憶單元所需的晶片面積要小好幾倍。SRAM 記憶單元也需要個別的電力來維持電晶體的狀態。DRAM 記憶單元的結構也較為簡單,這代表能較輕易地將許多記憶單元緊密地塞在一起。
簡單的方法也有其優點。最主要的優點是容量。比起一個 SRAM 的記憶單元,一個 DRAM 的記憶單元所需的晶片面積要小好幾倍。SRAM 記憶單元也需要個別的電力來維持電晶體的狀態。DRAM 記憶單元的結構也較為簡單,這代表能較輕易地將許多記憶單元緊密地塞在一起。

總體來說,贏在(極為戲劇性的)成本差異。除了在專門的硬體 –– 舉例來說,網路路由器 –– 之外,我們必須採用基於 DRAM 的主記憶體。這對程式開發者有著巨大的影響,我們將會在本文的其餘部分討論它們。但首先,我們需要先多理解一些實際使用 DRAM 記憶單元的細節。

10 changes: 5 additions & 5 deletions cpu-caches.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

比起僅僅 25 年前的 CPU,現今的 CPU 複雜得多。當時,CPU 核的頻率與記憶體匯流排在相同的等級,主記憶體存取僅略慢於暫存器存取。但這點在 1990 年代初期有所改觀,那時 CPU 設計者提升 CPU 核的頻率,但記憶體匯流排的頻率以及 RAM 晶片的效能並無等比例地成長。這不是因為無法發展出更快的 RAM,而是如前一節所解釋的。這是可能的,但並不經濟。與目前 CPU 核一樣快的 RAM,比起任何動態 RAM 都要貴上好幾個數量級。

一台有著非常小、非常快的 RAM 的機器,以及一台有著許多相對快速的 RAM 的機器,如果要在二者間擇一,在給定超過小小的 RAM 容量的工作集(working set)大小、以及存取硬碟這類次級儲存(secondary storage)媒體的成本之後,後者永遠是贏家。這裡的問題在於次級儲存裝置 –– 通常是硬碟 –– 的速度,它必須用以保存部分被移出(swap out)的工作集。存取這些硬碟甚至比 DRAM 存取要慢上好幾個數量級。
一台有著非常小、非常快的 RAM 的機器,以及一台有著許多相對快速的 RAM 的機器,如果要在二者間擇一,在給定超過小小的 RAM 容量的工作集(working set)容量、以及存取硬碟這類次級儲存(secondary storage)媒體的成本之後,後者永遠是贏家。這裡的問題在於次級儲存裝置 –– 通常是硬碟 –– 的速度,它必須用以保存部分被移出(swap out)的工作集。存取這些硬碟甚至比 DRAM 存取要慢上好幾個數量級。

幸運的是,不必做出非全有即全無 (all-or-nothing) 的選擇。一台電腦可以有一個小容量的高速 SRAM,再加上大容量的 DRAM。一個可能的實作會是,將處理器定址空間的某塊區域劃分來容納 SRAM,剩下的則給 DRAM。作業系統的任務就會是最佳化地分配資料以善用 SRAM。基本上,在這種情境下,SRAM 是作為處理器的暫存器集的擴充來使用的。

雖然這是可能的實作,但並不可行。忽略將 SRAM 記憶體的實體資源映射到處理器的虛擬(virtual)定址空間的問題(這本身就非常難),這個方法會需要令每個行程(process)在軟體上管理記憶體區域的分配。記憶體區域的大小因處理器而異(也就是說,處理器有著不同容量的昂貴 SRAM 記憶體)。組成一支程式的每個模組都會要求它的那份快速記憶體,這會由於同步的需求而引入額外的成本。簡而言之,擁有快速記憶體的獲益將會完全被管理資源的間接成本(overhead)給吃掉。
雖然這是可能的實作,但並不可行。忽略將 SRAM 記憶體的實體資源映射到處理器的虛擬(virtual)定址空間的問題(這本身就非常難),這個方法會需要令每個行程(process)在軟體上管理記憶體區域的分配。記憶體區域的容量因處理器而異(也就是說,處理器有著不同容量的昂貴 SRAM 記憶體)。組成一支程式的每個模組都會要求它的那份快速記憶體,這會由於同步的需求而引入額外的成本。簡而言之,擁有快速記憶體的獲益將會完全被管理資源的間接成本(overhead)給吃掉。

所以,並非將 SRAM 置於作業系統或者使用者的控制之下,而是讓它變成由處理器透明地使用與管理的資源。在這種方式下,SRAM 是用以產生主記憶體中可能不久就會被處理器用到的資料的暫時副本。因為程式碼與資料具有時間(temporal)與空間局部性(spatial locality)。這表示,在短時間內,很可能會重複用到同樣的程式碼或資料。對程式碼來說,這表示非常有可能會在程式碼中循環(loop),使得相同的程式碼一次又一次地執行(*空間局部性*的完美例子)。資料存取在理想上也會被限定在一小塊區域中。即使在短時間內用到的記憶體並非鄰近,同樣的資料也有很高的機會在不久後再次用到(*時間局部性*)。對程式碼來說,代表 –– 舉例來說 –– 在一輪迴圈中會產生一次函式呼叫(function call),這個函式在記憶體中可能很遠,但呼叫這個函式在時間上則會很接近。對資料來說,代表一次使用的記憶體總量(工作集大小)理想上是有限的,但使用的記憶體 –– 由於 RAM *隨機*存取的本質 –– 並不是相鄰的。理解局部性的存在是 CPU 快取概念的關鍵,因為我們至今仍在使用它們。
所以,並非將 SRAM 置於作業系統或者使用者的控制之下,而是讓它變成由處理器透明地使用與管理的資源。在這種方式下,SRAM 是用以產生主記憶體中可能不久就會被處理器用到的資料的暫時副本。因為程式碼與資料具有時間(temporal)與空間局部性(spatial locality)。這表示,在短時間內,很可能會重複用到同樣的程式碼或資料。對程式碼來說,這表示非常有可能會在程式碼中循環(loop),使得相同的程式碼一次又一次地執行(*空間局部性*的完美例子)。資料存取在理想上也會被限定在一小塊區域中。即使在短時間內用到的記憶體並非鄰近,同樣的資料也有很高的機會在不久後再次用到(*時間局部性*)。對程式碼來說,代表 –– 舉例來說 –– 在一輪迴圈中會產生一次函式呼叫(function call),這個函式在記憶體中可能很遠,但呼叫這個函式在時間上則會很接近。對資料來說,代表一次使用的記憶體總量(工作集容量)理想上是有限的,但使用的記憶體 –– 由於 RAM *隨機*存取的本質 –– 並不是相鄰的。理解局部性的存在是 CPU 快取概念的關鍵,因為我們至今仍在使用它們。

一個簡單的計算就能看出快取在理論上有多有效。假設存取主記憶體花費 200 個週期,而存取快取記憶體花費 15 個週期。接著,程式使用 100 個資料元素各 100 次,若是沒有快取,將會在記憶體操作上耗費 2,000,000 個循環,而若是所有資料都被快取過,只要 168,500 個週期。提升了 91.5%。

用作快取的 SRAM 大小比起主記憶體小了好幾倍。根據作者使用具有 CPU 快取的工作站(workstation)的經驗,快取的大小總是主記憶體大小的 1/1000 左右(現今:4MB 快取與 4GB 主記憶體)。單是如此並不會形成問題。假如工作集(正在處理的資料集)的大小比快取大小還小,這無傷大雅。但是電腦沒理由不擁有大量的主記憶體。工作集必定會比快取還大。尤其是執行多個行程的系統,其工作集的大小為所有個別的處理器與系統核心的大小總和
用作快取的 SRAM 容量比起主記憶體小了好幾倍。根據作者使用具有 CPU 快取的工作站(workstation)的經驗,快取的容量總是主記憶體容量的 1/1000 左右(現今:4MB 快取與 4GB 主記憶體)。單是如此並不會形成問題。假如工作集(正在處理的資料集)的容量小於快取,這無傷大雅。但是電腦沒理由不擁有大量的主記憶體。工作集必定會比快取還大。尤其是執行多個行程的系統,其工作集的容量為所有個別的處理器與系統核心的容量總和

應對快取的大小限制所需要的是,一組能在任何給定的時間點決定什麼該快取的策略。由於並非所有工作集的資料都會*正好*在相同的時間點使用,所以我們可以使用一些技術來暫時地將一些快取中的資料替換成別的資料。而且這也許能在真的需要資料之前就搞定。這種預取會去除一些存取主記憶體的成本,因為對程式的執行而言,這是非同步進行的。這所有的技術都能用來讓快取看起來比實際上還大。我們將會在 3.3 節討論它們。一旦探究完這全部的技術,協助處理器就是程式開發者的責任了。這些作法將會在第六節中討論。
應對快取的容量限制所需要的是,一組能在任何給定的時間點決定什麼該快取的策略。由於並非所有工作集的資料都會*正好*在相同的時間點使用,所以我們可以使用一些技術來暫時地將一些快取中的資料替換成別的資料。而且這也許能在真的需要資料之前就搞定。這種預取會去除一些存取主記憶體的成本,因為對程式的執行而言,這是非同步進行的。這所有的技術都能用來讓快取看起來比實際上還大。我們將會在 3.3 節討論它們。一旦探究完這全部的技術,協助處理器就是程式開發者的責任了。這些作法將會在第六節中討論。

Loading

0 comments on commit 66ad620

Please sign in to comment.