《深入理解計算機系統》筆記
一、首先復習一下
存儲越大尋址時間越慢、效率越低,雖然相對來說每一個數據計算機都會用到,但在某一階段、某一個特定時間,使用到的數據范圍是相對固定的。
處理器需要更快速的處理速度,需要快速得到指令和數據,而這些指令和數據都是存在低級的存儲中(硬盤等本地存儲或網絡存儲),單純拿硬盤來說,讀取時間就包括了傳輸時間、旋轉時間、尋道時間,效率太低。為了更快速的讓處理器得到數據,更好的利用處理器的性能,現代處理器演化出了分支預測的功能單元,可以讓處理器在未執行到某一個分支之前就通過投機先行計算(不在本次范圍內)。另外,除了內部的文件寄存器,計算機將處理器和主存之間增加了多級緩存,用來存放處理器需要用到的指令和數據。因此,處理器在活動時可以通過分支預測等技術同步的將后續將會使用到的指令和數據加載到緩存中(指令高速緩存/數據高速緩存),可以讓整個處理器流水線的效率更高。
注:L0,L1,L2,L3級緩存的效率都是成百倍的降低,L4主存的效率相比L1更是天差地別。客觀條件相同的情況下,存儲越大尋址速度越慢。雖然說從材料上面來說也有不同,不單單是大小的問題,但材料方面不在本次討論范圍內。
二、緩存
緩存是低層次存儲的緩存,或者說是對低層次緩存的“凝練和融合”(L1是L2的緩存,L2是L3的緩存)。通過建立一套規則和邏輯,我們將低層次存儲中的數據根據需要讀取到高層次緩存中。
本次說到的高速緩存的結構划分為以下幾個部分(概念)
組 行 數據塊
S E block

一個高速緩存的大小(C)就是 S*E*B(blockSize) 其中 B S 必須是2的N次冪
2.1 為什么要這么划分?
我們需要一套機制,將內存地址與高速緩存的索引之間建立關系,上面說的方式就是其中一種。
S代表了高速緩存的組數,E代表了每組中的行數,B代表每行中的數據塊大小,通過這S值和B值,我們就可以對內存地址進行掩碼處理,並得到相應的組值和數據塊偏移。
簡單分步驟的說:
1)計算機中的信息是用二進制表示的。
2)S組都是 2的N次冪,代表他們都是通過范圍的2進制位數表示的(如果S=5,那么值就可能是0,1,10,11,100,101;但三位二進數還有110、111的值,就無法用三位截取地址的方式來計算組索引了)
3)B數據塊也是2的N次冪,原因同S。
所以 s = log2(S) 就是 組索引在地址中的位數,b = log2(B)就是數據塊偏移的位數。
1000 1000 1000 1000
t s b
2.2 t是什么?
t代表標識,設想一下,既然是緩存,那么就是將低級存儲進行緩存,大小一定是比低級存儲更小,所以速度更快。更小代表着較多的數據要使用較小的位置,也就是說多個地址的數據使用一個緩存位置來存數(覆蓋什么規則后期再談),那么久需要一個標識來表示這個緩存單元中的數到底是哪個內存的,否則讀取數據的時候都不知道該讀哪個了。
t的公式是 memAddrLength - b - s。就是說,去掉組索引位和數據塊偏移位,剩下的就是標識位了。
2.3 結果呢,總體來說高速緩存到底什么樣子?
通過組和行我們把高速緩存划分成了一個樹形結構,當需要讀取低級存儲的時候,先將地址根據t s b的規則進行拆分,通過s找到相應的組(組數*行數*高速緩存單元的大小),再通過標識找到對應的行,然后根據塊偏移把數據讀出來。總的來說就是這么簡單。
實際上呢還有不少細節的問題,比如如果不命中怎么辦?如果命中的時候對應的高速緩存單元還沒熱身怎么辦(沒讀取數據)?如果現在內存地址對應的組都已經寫滿了應該替換哪一個? 等等,這些計算機現在都有相應的策略,感興趣的同學可以去看看書。
3.我要做什么
我准備用C語言自己寫一個高速緩存的機制試試,首先我沒有低級存儲(目前還不會硬件),低級存儲是用一個指針加一部分內存空間抽象的。而高速緩存也一樣,也在內存里,用一個指針加一部分內存空間抽象的。寫這個的目的是為了讓自己更好的理解高速緩存的原理。
實現的功能是:
1)實現高速緩存讀功能,可以根據內存地址進行掩碼處理得到對應的t s b值並從“高速緩存空間”中獲取到高速緩存單元。
2)實現高速緩存的寫功能,現在計划使用直寫的方式,即直接寫入到“低級存儲”中不根據高速緩存的寫狀態進行處理。
目前進行了組件設計和活動圖設計,圖如下:
1)組件圖:

2)交互圖

3)讀活動圖

4)寫活動圖

代碼后續會放到 git@code.aliyun.com:qdxiayongming/C.learn.git
望有有經驗的朋友指正。
