操作系統-cache高速緩存

問題

  • 在cache 中訪問的內存地址爲何會帶有 cache 相關的信息 ,動機是什麼?

前言

平時只知道cpu 到內存之間還有一層 cache , CPU 要去主存找一個數據 ,第一反應肯定是到先到 cache 中找 ,如果找不到再去主存中去找, 要是找到了,直接就返回了 . 上面的過程實際就是通過 主存地址 這個東西來判斷數據是否存在cache 中 . 其實主存地址在不同的地方是長不一樣的, 比如在 cache 裏面爲了去找一下 cache 有沒有 ,那麼是長這樣的, 假如是去主存找 ,那麼我首先得到頁表找 , 那麼主存地址又是長另外一個樣子 , 也就是說通過 主存地址 我們可以達到不同的目的 , 這一點需要記住 !

cache 在哪

下圖可以看到 cache 在寄存器和內存的中間 ,起到緩存的作用. 對內存進行緩存
1297993-20220410221408383-1437738747.png

1297993-20220410221732987-721157845.png

1297993-20220410221811991-1184201858.png

高速緩存如何工作

既然是對內存進行緩存, cache 的空間小, 內存的容量大, 可以看到緩存的單位是 Block (內存塊) , 內存塊內部其實還可以繼續細分 . cache 與內存之間的映射方法有三種

1297993-20220410221854066-1563792640.png

第一種方式 : 直接映射

我們首先對內存塊進行編號, 0號內存塊( 0 塊) , 1號內存塊( 1 塊 ), 2號內存塊, 3號內存塊 ...cache的記錄空間稱爲條數(行或者槽) ,如下圖 , 對 16 取餘數, 1塊 17塊 33塊 .., 2塊 18塊 34塊... 分到另外一個槽 . 分配過程假如衝突了就會發生替代, 例如我們的槽中原本放着 1號內存塊, 後來給 17號內存塊替代了.

1297993-20220410222911455-165372003.png

那我們看到 Cache 中這個表格的 0 號槽到底有沒有放數據啊 ,如果放了數據那麼放的是內存的第幾塊內存呢?? 所以這一定有兩個標識 :

  • 有無標識 v : 是否cache 裏面放了數據沒有的標識
  • tag : 標識槽位放的是第幾個塊羣的數據 , 例如 cache的 1號槽位 , 放有數據 ,並且tag 是 1 那麼我們就知道了 , 1號槽放的是內存第 17塊內存

搞懂了上面的內存的塊是如何放到 cache 裏面去的了. 我們再來看一下 CPU 發過來的主存地址是如何先去找 cache , 然後看看是否命中的 , CPU 發過來的地址有 20位 ,這 20位包括了
主存標識 + Cache 槽號 + 塊內地址 ,其中 :

  • 主存標識 : 就是哪一個塊羣

  • Cache 槽號 : Cache 哪一個槽號的

  • 塊內地址 : 內存塊中還再細分的

    例如我要找的地址是 0220CH , 變成二進制就是 0000 0010 0010 0000 1100B , 我首先到 0001(Cache 槽號) 槽位看一下是否存在數據, 假如是第一次 , cache 肯定是沒數據的 , cache 沒數據肯定需要將數據加載到內存中去 , 然後內存的數據再copy 到 cache 中去 , 那麼是內存的第幾塊內存啊 ? 看一下前 7位 --- 0000 001第一塊羣 , 第一塊羣放在 cache 的 1號槽 ,那隻能是17塊內存啦 !

    經過了這麼一頓操作 , 內存的 17塊內存已經被放在內存和 cache 中去了 ,第二次 ,我同樣訪問 地址是 0220CH, 同樣我先看Cache 槽號 , 裏面已經有數據了 ! (v標識表示有數據 ), 再比對一下是哪個塊羣 , 是 cache 的 1號槽 的第一塊羣 ( tag 也比中了!! ), 於是我就不再前往內存中拿數據了 , 因爲 cache 中有我想要的數據了

直接映射下的Cache 的標誌位

這裏的 tag 和 v 就是我們前面所說的標誌位

1297993-20220410224100401-1399537025.png

第一個位表示是否存在cache 中, 有效無效 , tag 則是當前 cache 裏的 data 取自哪個塊羣的 (因爲有可能來自不同的塊羣)

直接映射的另外一個例子

對比的時候先拿內存地址中的Cache 槽號 找到對應的 Cache記錄, 然後再對比該記錄中的 tag 是不是自己的塊羣, 要是是的話那麼繼續比對是否有效有效標識, 要是這都能對上說明內存塊存在 Cache 中呀!

1297993-20220410231939132-1864850891.png

直接映射的特點

我們前面也看到了每個塊對應於 cache 哪個位置是固定的, 那假如有幾個塊主存電腦用的比較頻繁, 但是都是同一個槽號的,比如 0號槽位的 0 ,16,32塊內存 , 那豈不是得頻繁的換進換出 ?? 是的 !!
img

第二種方式 : 全相聯映射Cache

全相聯映射的映射是這樣的, 只要有空的位置就往裏緩存 , 哈哈哈 , 反正有位置就放就完事了 ,沒位置就根據一定的規則把某些放太久的換出來,可以想象得到這肯定也有問題 ,比如

  • CPU 給個主存地址 ,我也不知道在不在 cache 槽裏, 那麼我就只能一個個對面,直到對比中了
  • 使用頻繁的塊內存肯定老是在槽裏 ,那麼使用頻率低的肯定都給擠出槽了

1297993-20220411163051233-744551371.png

這種方式就有意思了, CPU給過來的主存地址就只有兩部分的組成了

  • 標記/主存塊號
  • 塊內地址

比如CPU 傳過來 01E0CH , 轉化爲二進制就是 0000 0001 1110 0000 1100B , 前 11位表示的是15塊主存 , 我就那個 15 去 cache 對比一下 tag , 看一下 tag 裏面有沒有 15 ,有的話並且數據標識表示存在數據 ,那麼就是比中了 ,反之沒比中 !

第三種方式 : 組相聯映射

組相聯映射結合直接映射全相聯映射的特點 , 你看我們上面用全相聯映射的缺點是他喵的, 所有的主存塊亂放, 我他喵一個個對比 ,比到什麼時候嘛 , 於是組相聯映射 先將 cache 的容量進行分組 , 對應的內存塊只能放到對應的組呢 ,然後一組又有很多個空間, 這時候內存塊就可以隨便放 , 找的時候也是先找到對應的是哪一個組的,再在對應的組內進行比對

1297993-20220411163807086-1843804557.png

1297993-20220411165106235-1629057350.png

這個方法的主存地址, 第一部分,標記放的是位於內存中哪個塊羣, Cache索引是位於Cache哪個cache組 , 塊內地址 這個就不用解釋了

缺失率和關聯度

1297993-20220411170657791-1033362932.png

1297993-20220411170708293-2106172882.png

關聯度有點像查找命中的過程中掃描的條數

其他

關於虛擬地址 (重要)

之前以爲虛擬地址是一成不變的,其實這就是一個誤區, 這篇文章 cache 算是CPU 訪問數據的開端 , 認真想想, 對於內存來說, cache 是內存的緩存, 而對於磁盤來說 ,主存又是
磁盤的緩存, 我們學習這篇文章的時候 , 會發現內存地址放着關於 cache 目的就是訪問的時候,先到 cache 去找 ,我們後面還會學到頁表和 TLB , TLB 是頁表的緩存, 所以可想而知訪問頁表的內存地址也會有關於TLB 相關的信息 . 最後放上一張關於訪問內存的流轉圖 ! (重要)

1297993-20220411231735273-250349725.png

同樣的道理我們到時候也會看到在不同階段 ,內存地址會不一樣.

參考

  • <袁春風-操作系統>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章