部分節錄自概觀 CPU 快取
CPU 生成邏輯地址,其中包含page number和page offset。
page number用於對page table進行索引以獲取對應的page frame number,一旦我們找到physical memory(也稱為主內存)的page frame,我們就可以應用page offset來獲取page frame內正確的word。
L1 Cache中分為指令快取與資料快取,實驗證實分離程式碼與資料的快取是比較好的。Intel 自 1993 年起採用分離程式碼與資料的快取,就再也沒有回頭過。程式碼與資料所需的記憶體區域彼此相當獨立,這也是獨立的快取運作得更好的原因。近年來,另一個優點逐漸浮現:對大多數常見的處理器而言,指令解碼(decoding)的步驟是很慢的;快取解碼過的指令能夠讓執行加速,在不正確地預測或者無法預測的分支(branch)使得管線(pipeline)為空的情況下尤其如此。
隨著CPU製造工藝的發展,二級快取也能輕易的集成在CPU核心中,容量也在逐年提升。現在再用集成在CPU內部與否來定義一、二級快取,已不確切。
(Translation Look Aside Buffer)
問題是page table存儲在main memory中,有時可能非常大,所以為了加快邏輯地址到物理地址的轉換,我們有時使用昂貴且速度更快的cache組成TLB,(換言之,TLB 是負責改進虛擬地址到實體地址轉換速度、存放虛擬地址的快取)因此不是先進入page table(main memory中),我們進入TLB並使用page number索引,並獲取對應的page frame number,如果找到,我們完全避免使用page table即可找到對應的physical address.
如果在TLB中找不到對應的physical page frame,就稱為TLB miss,那我們就只好進入main memory中的page table來尋找。
當正在運行的Process欲存取的frame沒有登記在page table中(可能是frame不在main memory中也可能是page table錯誤),就稱為Page fault,則需要去secondary memory中載入到main memory中(swap in
)。
Cache是一種運行速度比main memory快的小內存,我們總是在訪問main memory之前先訪問cache。如果我們能夠在緩存內部找到相應的Word,就稱為cache hit,我們甚至不需要去main memory。
只有當相應的block(block類似於物理內存的frame)不在cache時,我們才去找TLB,然後找Page table…
所以流程基本上是這樣的
1 .首先到cache memory,如果cache hit,那麼就完成了。
2 . 如果cache miss,則需向 MMU 請求資料。
3 . 首先去TLB,如果TLB hit,就可以得到physical address,然後從二級快取 (存放的是實體地址的索引) 中讀取資料;如果 L2 cache 中也沒有,則需要從 L3 cache,甚至實體記憶體中請求;我們就完成了。
4 . 如果TLB miss,那麼去main memory中的page table來得到physical address。
5 . 如果page fault,只需從secondary memory加載所需的頁面進main memory並更新page table。如果main memory滿了,則使用page replacement algorithms。
以上討論是virtual cache的情況下(cache是使用virtual memory來索引,速度較快但每一行資料在原有tag的基礎上都要將程序標識加上以區分多個程序之間的相同地址,而在處理共享記憶體時也比較麻煩,共享記憶體在不同的程序中的虛擬地址不相同,如何同步是個問題。),若是physical cache流程會是3.4.5.1.2.(先將virtual memory轉換再去cache查找)。
按照工作原理來分,Cache又有physical index physical tagged, virtual index virtual tagged, physical index virtual tagged等幾種分法,我們來一一瞭解一下。
Physical index physical tagged是一種最容易理解的操作方式,Cache針對實體地址進行操作,簡單粗暴,而且不會有歧義。但是這種方式的缺陷也很明顯,在多程序作業系統中,每個程序擁有自己獨立的地址空間,指令和程式碼都是以虛擬地址的方式存在,CPU發出的memory access的指令都是以虛擬地址的方式發出,這樣的話,對於每一個memory access的操作,都要先等待MMU將虛擬地址翻譯為實體地址,這是一種序列的方式,效率較低。
Virtual index virtual tagged是純粹用虛擬地址來定址,這種方式帶來了更多的問題,每一行資料在原有tag的基礎上都要將程序標識加上以區分多個程序之間的相同地址或是在context switch時flush cache,而在處理共享記憶體時也比較麻煩,共享記憶體在不同的程序中的虛擬地址不相同,如何同步是個問題。引入虛擬地址的一個重要原因是在軟體(作業系統)級進行頁面保護,以防止行程間相互侵犯地址空間。由於這種保護是通過頁表和轉譯後備緩衝區(TLB)中的保護位(protection bit)實作的,直接使用虛擬地址來存取資料等於繞過了頁面保護。
現在比較多的是採用virtual index physical tagged的方式,virtual index的含義是當cpu發出一個地址請求之後,低位地址去和Cache中的index匹配, physical tagged是指虛擬地址的高位地址去和mmu中的頁表匹配以拿到實體地址(index和取實體地址這兩個過程是並行的),然後用從MMU中取到的實體地址作為tag(或者tag的一部分)去和Cache line的tag位匹配,這樣既保證了同一地址在Cache中的唯一性(有個例外,Cache alias)又能將MMU和Cache並行工作,提高了效率。這種方式帶來的唯一問題就是Cache alias,Cache alias主要發生在Cache大小同記憶體頁框大小不一致時,比如說每路Cache的大小是8k,而現在較為常用的頁框大小是4k,這兩個數字說明的問題分別是這樣的: