【計算機組成原理】:存儲系統學習(上)


一、程序的運行

馮諾依曼機的運行大致可分為兩個步驟,存儲程序和程序控制。具體而言,可分為以下步驟:

(1)輸入設備將程序與數據寫入內存;

(2)CPU取指令;

(3)CPU執行指令期間讀數據;

(4)CPU寫回運算結果;

(5)輸出設備輸出結果。


二、存儲系統層次結構

由於CPU和主存的運行速度相差較大,程序運行的速度就會受制於內存的速度。於是,存儲系統引入了高速緩存(Cache)。Cache的引入使得CPU訪問到的存儲系統具有Cache的速度,賦存的容量和價格。

image

同時,Cache又可以划分為L1 Cache和L2 Cache。其中L1 Cache集成在CPU中,分數據分數據Cache(D-Cache)和指令Cache(I-Cache)。早期L2 Cache在主板上或與CPU集成在同一電路板上。隨着工藝的提高L2 Cache被集成在CPU內核中,不分D-Cache和I-Cache。

image


三、主存中的數據

數據存放在內存中,分為按邊界存放和未按邊界存放。

(1)按邊界存放

按邊界存放的方式,在32位系統中,存儲單元為4個字節。int占4個字節,short占兩個字節,double占8個字節,char占1個字節。會產生空間空余。

image

(2)未按邊界存放

未按邊界存放充分利用了空間,但是增加了內存的訪問次數。如double類型的x,占了三個存儲單元,需要訪問三次。因此,這種方式雖然節省了空間,但增加了訪問內存的次數。

image


四、主存中的數據組織

知道了數據在內存中的存放方式,具體到代碼層面有什么影響呢?

如下兩種結構體的寫法:

struct S1{
    int i;
    char c;
    int j
}
struct S2{
    int i;
    int j
    char c;
}

在邊界對齊的情況下,這些數據在內存中的存儲如下圖所示。可以看到S1的結構體寫法占了12個字節,S2的結構體占了9個字節。但就一個結構體的數據而言,代碼的寫法確實可以節省空間。

image


五、Cache的基本原理

Cache主要是用來解決CPU與慢速的主存之間的速度差異。Cache的工作原理分為讀操作和寫操作。

(1)讀操作

image

如果Cache中已經有了該數據,就直接讀入,這個過程稱為命中(HIT)。如果Cache中沒有這個數據,就會從內存中讀取一個數據塊緩存到Cache中,接着從Cache中讀取到CPU,這個過程稱為缺失(MISS)。缺失會造成訪問速度急劇下降。

(2)寫操作

image

寫操作有兩種策略,寫穿策略(WriteThrough)和寫回策略(WriteBack)。寫穿策略是CPU向Cache中寫數據后,將Cache中的數據寫入到主存。寫回策略是CPU向Cache中寫數據后,不向主存寫入數據。寫回策略速度很快,但是數據的更新沒有刷新到主存。


六、Cache的地址映射機制

主存地址通常按照塊地址進行划分,Cache地址通常按照行進行划分,主存塊大小和Cache中的行大小相等。主存地址通常划分為三個部分,Tag用來判斷該數據是否在Cache中,Index用來找Cache中對於的數據位,塊內偏移用來查找對應數據。Cache的結構如下圖所示,Tag與主存Tag一致,Data用來存儲一行數據,Valid表示Cache中的數據是否有效,Dirty表示主存中的數據是否是最新的。

image

image

主存與Cache地址映射通常有三種方式,全相聯(fully-associated)、直接相聯(direct mapped)和組相聯(set-associated)。

(1)全映射

主存地址變成二維(塊號 塊內地址),如地址61,二進制是00111101,將它划分為兩部分 001111和01,其中001111是塊號,01是塊內地址。全映射的映射算法是主存的數據庫可以映射到Cache的任意行,同時將該數據塊地址對應行的標記存儲體中保存。

image

全映射的過程如上圖所示,若CPU的訪問序列順序為1F 20 24 1E。首先,對於1F地址,二進制為0001 1111,划分為二維后tag=000111,offset=11即第四哥單元。首先回判斷tag為000111是否命中,一開始是缺失的,因此添加tag為000111的單元,並把有效位置為1,同時從主存中讀取一個數據塊1C 1D 1E 1F到Cache中。其中偏移地址為11的1F即可訪問。20和24的訪問同理可得。當訪問到1E的時候,tag為000111的單元已經存在,此時是命中的狀態,可以直接去除偏移為10的數據。

可以看到,全相聯的映射Cache率很高,主存可以映射到Cache任意位置。同時,塊沖突率低,淘汰算法復雜。因此,全映射算法適用於小容量Cache。

(2)直接映射

直接映射將主存地址從一維變成三維(區號、區內塊號、塊內地址),如地址61二進制為00111101,划分為000011 11 01。直接映射的映射算法是,假設Cache有n行,主存第j塊號映射到Cache的行號為i=j mod n ,即內存的數據塊映射到Cache的特定行。

image

直接映射的過程如上圖所示,若訪問順序為1F 20 24 1E 44。首先對於1F,地址划分為tag=0000,index=111,offset=11。因此,1F這個數據塊只能映射到第7行。 如果某一行中,已經有了數據,且tag不一致,那么就會發生碰撞。這種情況下就會覆蓋掉原來的數據。

直接映射的特點是Cache的利用率低,只能映射到特定行中。塊沖突率高,淘汰算法簡單,適用於大容量的Cache。

(3)組相聯映射

組相連映射把地址從一維變成三維(組號、組內塊號、塊內地址)。如地址61划分為0000111 1 01。組內映射算法是Cache共n組,主存第j塊號映射到Cache 的組號為: i=j mod n 即主存的數據塊映射到Cache特定組的任意行。

image

組相聯映射會把數據映射到對應組的任意行,接着根據tag進行判斷是否命中,如果該組已經滿了,就會發生碰撞。組相聯映射相當於全相聯映射和直接映射的折中。下圖說明了組相聯與其它兩種方式的關系。若Cache有8行,當組相聯數k=8時,組相聯就變成了全相聯。當k=1時,就變成了直接相聯。

image


七、替換算法

當程序運行一段時間后,Cache存儲空間被占滿,當再有新數據要調入時,就需要通過某種機制決定替換的對象。因此,就需要替換算法。常見的替換算法有:先進先出法(FIFO,First in First out),最不經常使用法(LFU,Least Frequently Used),近期最少使用法(LRU,Least recently Used),隨機替換法。

(1)先進先出法(FIFO)

image

先進先出法,顧名思義就是當需要替換時,先被訪問的最先被替換。如上圖,22載入添加一個標記0,后面沒載入一次標記+1,依次載入到22 11 19 7,其中22命中一次。當載入16時,Cache已經滿了。這時候需要采用先進先出的替換算法,其中22是最先被載入的,因此替換22。

(2)最不經常使用法(LFU)

image

最不經常使用法,就是優先替換掉命中次數最少的行,如果命中次數相同,可以搭配其它替換策略,如FIFO。如上圖,當載入4時,22的次數為2,11的次數為1,19和16的次數為0。因此替換掉先進來的19。同理,當載入3時,優先替換掉次數少且先進來的16。

(3)近期最少使用法(LRU)

image

近期最少使用法,就是優先替換掉很長一段時間沒有命中的單元。每次載入,如果命中則標記清0,否則標記+1。如上圖所示,當載入16時,優先替換標記最大的11,載入4時,優先替換最大的22。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM