- 嵌入式系統(tǒng)Linux內(nèi)核開發(fā)實戰(zhàn)指南(ARM平臺)
- 王洪輝編著
- 1136字
- 2018-12-27 18:21:39
第5章 ARM處理器的Cache和Write Buffer
Cache是位于CPU與主存儲器即DRAM(Dynamic RAM,動態(tài)存儲器)之間的少量超高速靜態(tài)存儲器SRAM(Static RAM),它是為了解決CPU與主存之間速度匹配問題而設置的,不能由用戶直接尋址訪問。隨著科技的發(fā)展和生產(chǎn)工藝水平的提高,高性能處理器中Cache的容量將越來越大,而且級數(shù)將越來越多,從而大大提高系統(tǒng)的性能。
5.1 Cache和Write Buffer一般性介紹
本節(jié)我們摘錄一些網(wǎng)上介紹Cache和Write Buffer的文章,以期讀者能對Cache和Write Buffer有一個比較深刻的認識。按照先一般性后個性的順序,我們后面章節(jié)再介紹ARM處理器中的Cache和Write Buffer時就會比較容易理解。
5.1.1 Cache工作原理
具有Cache的計算機,當CPU需要進行存儲器存取時,首先檢查所需數(shù)據(jù)是否在Cache中。如果存在,則可以直接存取其中的數(shù)據(jù)而不必插入任何等待狀態(tài),這是最佳情況,稱為高速命中;當CPU所需信息不在Cache中時,則需切換存取主儲器,由于速度較慢,需要插入等待,這種情況稱高速未命中;在CPU存取主存儲器的時候,按照最優(yōu)化原則將存儲信息同時寫入到Cache中以保證下次可能的高速緩存命中。因此,同一數(shù)據(jù)可能同時存儲在主存儲器和Cache中。同樣,按照優(yōu)化算法,可以淘汰Cache中一些不常使用的數(shù)據(jù)。
傳統(tǒng)的Socket架構(gòu)通常采用兩級緩沖結(jié)構(gòu),即在CPU中集成了一級緩存(L1 Cache),在主板上裝二級緩存(L2 Cache),而SlotⅠ架構(gòu)下的L2 Cache則與CPU做在同一塊電路板上,以內(nèi)核速度或者內(nèi)核速度的一半運行,速度比Socket下的以系統(tǒng)外頻運行的L2 Cache更快,能夠更大限度發(fā)揮高主頻的優(yōu)勢,當然對Cache工藝要求也更高。CPU首先在L1 Cache中查找數(shù)據(jù),如找不到,則在L2 Cache中尋找。若數(shù)據(jù)在L2 Cache中,控制器在傳輸數(shù)據(jù)的同時,修改L1 Cache;若數(shù)據(jù)既不在L1 Cache中,又不在L2 Cache中,Cache控制器則從主存中獲取數(shù)據(jù),將數(shù)據(jù)提供給CPU的同時修改兩級Cache。K6-Ⅲ則比較特殊,64KB L1 Cache,256KB Full Core Speed L2 Cache,原先主板上的緩存實際上就成了L3 Cache。根據(jù)有關測試表明:當512K~2MB的三級緩存發(fā)揮作用時,系統(tǒng)性能還可以有2%~10%的提高;Tri-level成為PC系統(tǒng)出現(xiàn)以來提出的解決高速CPU與低速內(nèi)存之間瓶頸最為細致復雜的方案;而且,今后Cache的發(fā)展方向也是大容量、超高速。
在主存-Cache存儲體系中,所有的指令和數(shù)據(jù)都存在主存中,Cache只是存放主存中的一部分程序塊和數(shù)據(jù)塊的副本,只是一種以塊為單位的存儲方式。Cache和主存被分為塊,每塊由多個字節(jié)組成。由上述的程序局部性原理可知,Cache中的程序塊和數(shù)據(jù)塊會使CPU要訪問的內(nèi)容在大多數(shù)情況下已經(jīng)在Cache中,CPU的讀寫操作主要在CPU和Cache之間進行。CPU訪問存儲器時,送出訪問單元的地址,由地址總線傳送到Cache控制器中的主存地址寄存器MA,主存-Cache地址轉(zhuǎn)換機構(gòu)從MA獲取地址并判斷該單元內(nèi)容是否已在Cache中存有副本,如果副本已存在于Cache中,即命中。當命中時,立即把訪問地址變換成它在Cache中的地址,然后訪問Cache。
如果CPU要訪問的內(nèi)容不在Cache中,即不命中,則CPU轉(zhuǎn)去直接訪問主存,并將包含此存儲單元的整個數(shù)據(jù)塊(包括該塊數(shù)據(jù)的地址信息)傳到Cache中,使得以后的若干次對內(nèi)存的訪問可轉(zhuǎn)化為對Cache的訪問。若Cache存儲器已滿,則需在替換控制部件的控制下,根據(jù)某種替換算法/策略,用此塊信息替換掉Cache中原來的某塊信息。
所以,要想提高系統(tǒng)效率,必須提高Cache命中率,而Cache命中率的提高則取決于Cache的映像方式和Cache刷新算法等一系列因素,同時Cache中內(nèi)容應與主存中的部分保持一致,也就是說,如果主存中的內(nèi)容在調(diào)入Cache之后發(fā)生了變化,那么它在Cache中的映像也應該隨之發(fā)生相應改變,反之,當CPU修改了Cache中的內(nèi)容后,主存中的相應內(nèi)容也應作修改。
5.1.2 地址映像方式
所謂地址映像方式是指如何確定Cache中的內(nèi)容是主存中的哪一部分的副本,即必須應用某種函數(shù)把主存地址映像到Cache中定位。當信息按某種方式裝入Cache中后,執(zhí)行程序時,應將主存地址變換為Cache地址,這個變換過程叫作地址變換。地址映像方式通常采用直接映像、全相聯(lián)映像、組相聯(lián)映像三種:
直接映像
每個主存地址映像到Cache中的一個指定地址的方式,稱為直接映像方式。在直接映像方式下,主存中存儲單元的數(shù)據(jù)只可調(diào)入Cache中的一個位置,如果主存中另一個存儲單元的數(shù)據(jù)也要調(diào)入該位置則將發(fā)生沖突。地址映像的方法一般是將主存空間按Cache的尺寸分區(qū),每區(qū)內(nèi)相同的塊號映像到Cache中相同的塊位置。一般地,Cache被分為2N塊,主存被分為大小為2MB的塊,主存與Cache中塊的對應關系可用如下映像函數(shù)表示:j = i mod 2N。式中,j是Cache中的塊號;i是主存中的塊號。
直接映像是一種最簡單的地址映像方式,它的地址變換速度快,而且不涉及其他兩種映像方式中的替換策略問題。但是這種方式的塊沖突概率較高,當程序往返訪問兩個相互沖突的塊中的數(shù)據(jù)時,Cache的命中率將急劇下降,因為這時即使Cache中有其他空閑塊,也因為固定的地址映像關系而無法應用。
全相聯(lián)映像
主存中的每一個字塊可映像到Cache任何一個字塊位置上,這種方式稱為全相聯(lián)映像。這種方式只有當Cache中的塊全部裝滿后才會出現(xiàn)塊沖突,所以塊沖突的概率低,可達到很高的Cache命中率,但它實現(xiàn)很復雜。當訪問一個塊中的數(shù)據(jù)時,塊地址要與Cache塊表中的所有地址標記進行比較已確定是否命中。在數(shù)據(jù)塊調(diào)入時存在著一個比較復雜的替換問題,即決定將數(shù)據(jù)塊調(diào)入Cache中什么位置,將Cache中哪一塊數(shù)據(jù)調(diào)出主存。為了達到較高的速度,全部比較和替換都要用硬件實現(xiàn)。
組相聯(lián)映像
組相聯(lián)映像方式是直接映像和全相聯(lián)映像的一種折中方案。這種方法將存儲空間分為若干組,各組之間是直接映像,而組內(nèi)各塊之間則是全相聯(lián)映像。它是上述兩種映像方式的一般形式,如果組的大小為1,即Cache空間分為2N組,就變?yōu)橹苯佑诚瘢蝗绻M的大小為Cache整個的尺寸,就變?yōu)槿嗦?lián)映像。組相聯(lián)方式在判斷塊命中及替換算法上都要比全相聯(lián)方式簡單,塊沖突的概率比直接映像低,其命中率也介于直接映像和全相聯(lián)映像方式之間。
5.1.3 Cache寫入方式原理簡介
提高高速緩存命中率的最好方法是盡量使Cache存放CPU最近一直在使用的指令與數(shù)據(jù),當Cache裝滿后,可將相對長期不用的數(shù)據(jù)刪除,提高Cache的使用效率。為保持Cache中數(shù)據(jù)與主存儲器中數(shù)據(jù)的一致性,避免CPU在讀寫過程中將Cache中的新數(shù)據(jù)遺失,造成錯誤地讀數(shù)據(jù),確保Cache中更新過程的數(shù)據(jù)不會因覆蓋而消失,必須將Cache中的數(shù)據(jù)更新及時準確地反映到主存儲器中,這是一個Cache寫入過程,Cache寫入的方式通常采用直寫式、緩沖直寫式與回寫式三種,下面比較介紹這三種Cache寫入方式。
■ 直寫式(Write Through)系統(tǒng)
CPU對Cache寫入時,將數(shù)據(jù)同時寫入到主存儲器中,這樣可保證Cache中的內(nèi)容與主存儲器的內(nèi)容完全一致。這種方式比較直觀,而且簡單、可靠,但由于每次對Cache更新時都要對主存儲器進行寫操作,而這必須通過系統(tǒng)總線來完成,因此總線工作頻繁,系統(tǒng)運行速度就會受到影響。
■ 緩沖直寫式(Post Wirte)系統(tǒng)
為解決直寫式系統(tǒng)對總線速度的影響問題,在主存儲器的數(shù)據(jù)寫入時增加緩沖器區(qū)。當要寫入主存儲器的數(shù)據(jù)被緩沖器鎖存后,CPU便可執(zhí)行下一個周期的操作,不必等待數(shù)據(jù)寫入主存儲器。這相對于給主存儲器增加了一個單向單次高速緩存。比如,在寫入周期之后可以緊接著一個數(shù)據(jù)已存在于Cache中的讀取周期,這樣就可避免直寫式系統(tǒng)造成的操作延時,但這個緩沖器只能存儲一次寫入的數(shù)據(jù),當連續(xù)兩次寫操作發(fā)生時,CPU仍需等待。
■ 回寫式(Write Back)系統(tǒng)
前面兩種寫入方式系統(tǒng),都是在寫Cache的同時對主存儲器進行寫操作。實際上這不僅是對總線帶寬的占用,浪費了寶貴的執(zhí)行時間,而且在有些情況下是不必要的,可以通過增加額外的標準來判斷是否有必要更新數(shù)據(jù)。回寫式系統(tǒng)就是通過在Cache中的每一數(shù)據(jù)塊的標志字段中加入一更新位,解決主存儲器不必要的寫操作。比如,若Cache中的數(shù)據(jù)曾被CPU更新過但還未更新主存儲器,則該更新位被置1。每次CPU將一塊新內(nèi)容寫入Cache時,首先檢查Cache中該數(shù)據(jù)塊的更新位,若更新位為0,則將數(shù)據(jù)直接寫入Cache;反之,若更新位為1,則先將Cache中的該項內(nèi)容寫入到主存儲器中相應的位置,再將新數(shù)據(jù)寫回Cache中。
與直寫式系統(tǒng)相比,回寫式系統(tǒng)可省下一些不必要的立即回寫操作,而在許多情況下這是很頻繁出現(xiàn)的。即使一個Cache被更新,若未被新的數(shù)據(jù)所取代,則沒有必要立刻進行主存儲器的寫操作。也就是說,實際寫入主存儲器的次數(shù),可能少于CPU實際所執(zhí)行寫入周期的次數(shù),但回寫式系統(tǒng)的結(jié)構(gòu)較復雜,Cache也必須用額外的容量來存儲標志。由于回寫系統(tǒng)的高效率,現(xiàn)代的Cache大多采取這種方式進行操作。
5.1.4 關于Write-through和Write-back
■ 對于磁盤操作來說
write-through的意思是寫操作根本不使用緩存,數(shù)據(jù)總是直接寫入磁盤,關閉寫緩存,可釋放緩存用于讀操作(緩存被讀寫操作共用)。
write-back的意思是數(shù)據(jù)不直接被寫入磁盤,而是先寫入緩存,再由控制器將緩存內(nèi)未寫入磁盤的數(shù)據(jù)寫入磁盤,從應用程序的角度看,比等待完成磁盤寫入操作要快得多,因此可以提高寫性能。
但是write-back(write cache)方式通常在磁盤負荷較輕時速度更快。負荷重時,每當數(shù)據(jù)被寫入緩存后,就要馬上再寫入磁盤以釋放緩存來保存將要寫入的新數(shù)據(jù),這時如果數(shù)據(jù)直接寫入磁盤,控制器會以更快的速度運行。因此,負荷重時,將數(shù)據(jù)先寫入緩存反而會降低吞吐量。
■ 對于CPU內(nèi)部的cache緩沖模式來說
Write-Through和Write-Back,前者是按順序來一個寫一個,而后者則是先將資料按一定數(shù)量保存在緩沖區(qū)中,然后將相同位置的數(shù)據(jù)一次性寫出。舉例說明:有一部電梯,如果按先入先出的原則,即write through模式,第一個人去3樓,第二個去2樓,第三個也去3樓,那么這電梯就得先到3樓,然后到2樓,再去3樓。但如果在write back模式下,電梯先到2樓把第二個人送出去,然后再到3樓把第一個人和第三個人送出去,效率顯然高多了。早期的cache只有write through模式,但現(xiàn)在的cache都使用write back模式了。
■ 其他的解釋
Write-Through:在write的時候,同步更新cache和memory中的數(shù)據(jù)。
Write-Back:在write的時候更新cache,但是memory中的數(shù)據(jù)不一定同步更新,只有當cache到一定程度才會把cache中的數(shù)據(jù)刷到memory中,或者通過cache指令刷新,不會同步自動刷新。
cache line的意思是假設你那條指令只要從memory中讀4個字節(jié),但是一般來說你接下來的指令很有可能要讀這4個字節(jié)后面的數(shù)據(jù),所以一般硬件會多讀一些數(shù)據(jù)進入cache,比如64字節(jié),那么這64字節(jié)就是一個cache line。而如果你這個cache line里的數(shù)據(jù)長時間不被CPU訪問,那么這個cache line可能會被選中換出,這時候就必須把cache里被改過的信息寫回memory了。
5.1.5 Cache替換策略
Cache和存儲器一樣具有兩種基本操作,即讀操作和寫操作。當CPU發(fā)出讀操作命令時,根據(jù)它產(chǎn)生的主存地址分為兩種情形:一種是需要的數(shù)據(jù)已在Cache中,那么只需要直接訪問Cache,從對應單元中讀取信息到數(shù)據(jù)總線即可;另一種是需要的數(shù)據(jù)尚未裝入Cache,CPU需要從主存中讀取信息的同時,Cache替換部件把該地址所在的那塊存儲內(nèi)容從主存復制到Cache中。若Cache中相應位置已被字塊占滿,就必須去掉舊的字塊。常見的替換策略有以下兩種:
先進先出策略(FIFO)
FIFO(First In First Out)策略總是把最先調(diào)入的Cache字塊替換出去,它不需要隨時記錄各個字塊的使用情況,較容易實現(xiàn)。缺點是經(jīng)常使用的塊,如一個包含循環(huán)程序的塊也可能由于它是最早的塊而被替換掉。
最近最少使用策略(LRU)
LRU(Least Recently Used)策略是把當前近期Cache中使用次數(shù)最少的信息塊替換出去,這種替換算法需要隨時記錄Cache中字塊的使用情況。LRU的平均命中率比FIFO高,在組相聯(lián)映像方式中,當分組容量加大時,LRU的命中率也會提高。
5.1.6 使用Cache的必要性
所謂Cache即高速緩沖存儲器,它位于CPU與主存即DRAM之間,是通常由SRAM構(gòu)成的規(guī)模較小但存取速度很快的存儲器。目前計算機主要使用的內(nèi)存為DRAM,它具有價格低、容量大等特點,但由于使用電容存儲信息,存取速度難以提高,而CPU每執(zhí)行一條指令都要訪問一次或多次主存,DRAM的讀寫速度遠低于CPU速度,因此為了實現(xiàn)速度上的匹配,只能在CPU指令周期中插入wait狀態(tài),高速CPU處于等待狀態(tài)將大大降低系統(tǒng)的執(zhí)行效率。由于SRAM采用了與CPU相同的制作工藝,因此與DRAM相比,它的存取速度快,但體積大、功耗大、價格高,不可能也不必要將所有的內(nèi)存都采用SRAM。因此為了解決速度與成本的矛盾就產(chǎn)生了一種分級處理的方法,即在主存和CPU之間加裝一個容量相對較小的SRAM作為高速緩沖存儲器。當采用Cache后,在Cache中保存著主存中部分內(nèi)容的副本(稱為存儲器映像),CPU在讀寫數(shù)據(jù)時,首先訪問Cache(由于Cache的速度與CPU相當,所以CPU可以在零等待狀態(tài)下完成指令的執(zhí)行),只有當Cache中無CPU所需的數(shù)據(jù)時(這稱之“未命中”,否則稱為“命中”),CPU才去訪問主存。而目前大容量Cache能使CPU訪問Cache命中率高達90%~98%,從而大大提高了CPU訪問數(shù)據(jù)的速度,提高了系統(tǒng)的性能。
5.1.7 使用Cache的可行性
對大量的典型程序的運行情況分析結(jié)果表明,在一個較短的時間內(nèi),由程序產(chǎn)生的地址往往集中在存儲器邏輯地址空間的很小范圍內(nèi)。在多數(shù)情況下,指令是順序執(zhí)行的,因此指令地址的分布就是連續(xù)的,再加上循環(huán)程序段和子程序段要重復執(zhí)行多次,因此對這些地址的訪問就自然具有時間上集中分布的趨向。數(shù)據(jù)的這種集中傾向不如指令明顯,但對數(shù)組的訪問以及工作單元的選擇都可以使存儲器地址相對集中。這種對局部范圍的存儲器地址的頻繁訪問,而對此范圍以外的地址則訪問甚少的現(xiàn)象稱為程序訪問的局部性。根據(jù)程序的局部性原理,在主存和CPU之間設置Cache,把正在執(zhí)行的指令地址附近的一部分指令或數(shù)據(jù)從主存裝入Cache中,供CPU在一段時間內(nèi)使用,是完全可行的。
5.2 ARM處理器中的Cache和Write Buffer
5.2.1 基本概念

5.2.2 Cache工作原理
在cache存儲系統(tǒng)中,把cache和主存儲器都劃分成相同大小的塊。主存地址由塊號B和塊內(nèi)地址W兩部分組成,cache地址由塊號b和塊內(nèi)地址w組成。當CPU訪問cache時,CPU送來主存地址,放到主存地址寄存器中,通過地址變換部件把主存地址中的塊號B變換成cache的塊號b,并放到cache地址寄存器中,同時將主存地址中的塊內(nèi)地址W直接作為cache的塊內(nèi)地址w裝入cache地址寄存器中,如果變換成功(又叫cache命中),就用得到的cache地址去訪問cache,從cache中取出數(shù)據(jù)送到CPU中;如果變換不成功(cache不命中),則產(chǎn)生cache失效信息,并且用主存地址訪問主存儲器,從主存儲器中讀出一個字送往CPU,同時把包含該字在內(nèi)的一整塊數(shù)據(jù)都從主存儲器讀出來裝入cache,這時,如果cache已經(jīng)滿了,則要采用某種cache替換策略把不常用的塊先調(diào)出到主存儲中相應的塊中,以便騰出空間來存放新調(diào)入的塊。由于程序具有局部性特點,每次塊失效時都把一塊(由多個字組成)調(diào)入到cache中,能夠提高cache的命中率。
5.2.3 Cache地址映射和變換方法
地址的映射和變換是密切相關的,采用什么樣的地址映射方法就必然有與這種映射方法相對應的地址變換方法。無論采用什么樣的地址映射方式和地址變換方式,都要把主存和cache劃分成同樣大小的存儲單位,每個存儲單位成為“塊”,在進行地址映射和變換時,都是以塊為單位進行的。常用的映射方式和變換方式有以下3種:
■ 全相聯(lián)映射方式
主存中任意一塊可以映射到cache中的任意一塊上。
■ 直接映射方式
主存中一塊只能映射到cache中的一個特定塊上,假定主存的塊號為B,cache的塊號為b,cache的總塊數(shù)為Cb,則它們之間的映射關系可以用下面的公式表示:
b = B mode Cb
■ 組相連映射方式
在這種相聯(lián)的地址映射和變換方式中,把主存和cache按同樣大小劃分成組(set),每個組都由相同塊數(shù)組成。從主存的組到cache的組之間采用直接映射方式,在主存中的組與cache中的組之間建立好映射關系之后,在兩個對應的組內(nèi)部采用全相聯(lián)的映射方式。
在ARM處理器中,主存與cache采用組相聯(lián)地址映射和變換方式,如果cache的塊大小為2L,則同一塊中各地址的bit[31:L]是相同的。如果cache中組的大小(每組中包含的塊數(shù))為2S,則虛擬地址的bit[L+S-1:L]用于選擇cache中的某個組,而虛擬地址中其他位[31:L+S]包含了一些標志。
將cache每組中的塊數(shù)稱為組容量(set-associativity),當組容量等于cache中的總塊數(shù)時,對應的映射方式為全相聯(lián)映射方式;當組容量等于1時,對應的映射方式為直接映射方式;當組容量為其他值時,稱為組相聯(lián)映射方式。
在組相聯(lián)映射方式中,cache的大小CACHE_SIZE(字節(jié)數(shù))可以通過下面的公式來計算:
CACHE_SIZE = LINELEN*ASSOCIATIVITY*NSETS
其中,LINELEN為cache塊(line)大小;ASSOCIATIVITY為組容量;NSETS為cache的組數(shù)。
5.2.4 Cache分類
根據(jù)不同的分類標準可以按以下3種方法對Cache進行分類。
1)數(shù)據(jù)cache和指令cache
● 指令cache:指令預取時使用的cache。
● 數(shù)據(jù)cache:數(shù)據(jù)讀寫時使用的cache。
如果一個存儲系統(tǒng)中指令cache和數(shù)據(jù)cache是同一個cache,稱系統(tǒng)使用了統(tǒng)一的cache。反之,如果是分開的,那么稱系統(tǒng)使用了獨立的cache;如果系統(tǒng)中只包含指令cache或者數(shù)據(jù)cache,那么在配制系統(tǒng)時可以作為獨立的cache使用了。
使用獨立的數(shù)據(jù)cache和指令cache,可以在同一個時鐘周期中讀取指令和數(shù)據(jù),而不需要雙端口的cache,但這時候要注意保證指令和數(shù)據(jù)的一致性。
2)寫通(write-through)cache和寫回(write-back)cache
● 寫回cache
CPU在執(zhí)行寫操作時,被寫的數(shù)據(jù)只寫入cache,不寫入主存,僅當需要替換時,才把已經(jīng)修改的cache塊寫回到主存中,在采用這種更新算法的cache快表中,一般有一個修改位,當一塊中的任何一個單元被修改時,這一塊的修改位被設置為1,否則這一塊的修改位仍保持為0;在需要替換這一塊時,如果對應的修改位為1,則必須先把這一塊寫到主存中去之后,才能調(diào)入新的塊,否則,只要用新調(diào)入的塊覆蓋該塊即可。
● 寫通cache
CPU在執(zhí)行寫操作時,必須把數(shù)據(jù)同時寫入cache和主存,這樣,在cache的快表中就不需要“修改位”,當某一塊需要替換時,也不必把這一塊寫回到主存中,新調(diào)入的塊可以立即把這一塊覆蓋掉。
寫回cache和寫通cache的優(yōu)缺點比較如表5-1所示。

表5-1寫回cache與寫通cache比較
3)讀時分配(read-allocate)cache和寫時分配(write-allocate)cache
● 讀時分配cache
當進行數(shù)據(jù)寫操作時,如果cache沒命中,只是簡單地將數(shù)據(jù)寫入主存中,主要在數(shù)據(jù)讀取時,才進行cache內(nèi)容預取。
● 寫時分配cache
當進行數(shù)據(jù)寫操作時,如果cache未命中,cache系統(tǒng)將會進行cache內(nèi)容預取,從主存中將相應的塊讀取到cache中相應的位置,并執(zhí)行寫操作,把數(shù)據(jù)寫入到cache中。對于寫通類型的cache,數(shù)據(jù)將會同時寫入到主存中,對于寫回類型的cache,數(shù)據(jù)將在合適的時候?qū)懟氐街鞔嬷小?/p>
由于寫操作分配cache增加了cache內(nèi)容預取的次數(shù),增加了寫操作的開銷,但同時可能提高cache的命中率,因此這種技術對于系統(tǒng)整體性能的影響與程序中讀操作和寫操作的數(shù)量有關。
5.2.5 Cache替換算法
隨機替換算法
通過一個偽隨機數(shù)發(fā)生器產(chǎn)生一個偽隨機數(shù),用新塊編號為該偽隨機數(shù)的cache塊替換掉。這種算法很簡單且容易實現(xiàn),但沒有考慮程序的局部性特點,也沒有利用歷史上塊地址流的分布情況,因而效果較差,同時這種算法不易預測最壞情況下cache的性能。
輪轉(zhuǎn)替換算法
維護一個邏輯的計數(shù)器,利用該計數(shù)器依次選擇將要被替換出去的cache塊。這種算法容易預測在最壞情況下cache的性能。但在程序發(fā)生很小的變化時,可能造成cache平均性能的急劇變化,這是它的一個明顯缺點。
5.2.6 Cache內(nèi)容鎖定
“鎖定”在cache中的塊在常規(guī)的cache替換操作中不會被替換,但當通過C7控制cache中特定的塊時,比如使某特定的塊無效時,這些被“鎖定”在cache中的塊也將受到相應的影響。
用LINELEN表示cache的塊大小,用ASSOCIATIVITY表示每個cache組中的塊數(shù),用NSETS表示cache中的組數(shù)。cache的“鎖定”是以鎖定塊(lockdown block)為單位進行的。每個鎖定塊中包括cache中每個組中各一個塊,這樣cache中最多可有ASSOCIATIVITY個鎖定塊,編號為0~ASSOCIATIVITY-1。其中編號為0的鎖定塊中包含cache組0中的0號塊、組1中的0號塊,一直到ASSOCIATIVITY-1中的0號塊。
“N鎖定塊被鎖定”是指編號為0~N-1的鎖定塊被鎖定在cache中,編號為N~ASSOCIATIVITY-1的鎖定塊可用于正常的cache替換操作。
實現(xiàn)N鎖定塊被鎖定的操作步驟說明如下:
1)確保在整個鎖定過程中不會發(fā)生異常中斷,否則必須保證與該異常中斷相關的代碼和數(shù)據(jù)位于非緩沖(uncachable)的存儲區(qū)域。
2)如果鎖定的是指令cache或者統(tǒng)一的cache,必須保證鎖定過程所執(zhí)行的代碼位于非緩沖的存儲區(qū)域。
3)如果鎖定的是數(shù)據(jù)cache或者統(tǒng)一的cache,必須保證鎖定過程所涉及的數(shù)據(jù)位于非緩沖的存儲區(qū)域。
4)確保將要被鎖定的代碼和數(shù)據(jù)位于緩沖(cachable)的存儲區(qū)域。
5)確保將要被鎖定的代碼和數(shù)據(jù)尚未在cache中,可以通過使無效相應cache中的塊達到這一目的。
6)對于I=0到N-1,重復執(zhí)行下面的操作:
a)Index=I寫入CP15的C9寄存器,當使用B格式的鎖定寄存器時,令L=1;
b)在鎖定塊I中的各cache塊內(nèi)容從主存中預取到cache中,對于數(shù)據(jù)cache和統(tǒng)一cache可以使用LDR指令讀取一個位于該塊中的數(shù)據(jù),將塊預取到cache中;對于指令cache,通過操作CP15的C7寄存器,將相應的塊預取到指令cache中。
7)將index=N寫入CP15的C9寄存器,當使用B格式的鎖定寄存器時,令L=0。
解除N鎖定塊被鎖定只須執(zhí)行以下操作:
將index=0寫入CP15的C9寄存器,當使用B格式的鎖定寄存器時,令L=0。
5.2.7 MMU映射描述符中B位和C位的含義
見表5-2。
表5-2 存儲空間緩沖特性的控制位

5.2.8 Cache和Writer Buffer編程接口
ARM處理器中的Cache和Write Buffer操作是通過寫CP15的C7寄存器來實現(xiàn)的。訪問CP15的C7寄存器的指令格式如下所示:
mcr p15, 0, <rd>, <c7>, crm, <opcode_2>
ARM處理器中的Cache和Write Buffer操作指令如表5-3所示。
表5-3 ARM處理器Cache和Write Buffer操作指令

5.3 ARM處理器的快速上下文切換技術
5.3.1 FCSE概述
FCSE(Fast Context Switch Extension,快速上下文切換)位于CPU和MMU之間,如果兩個進程使用了同樣的虛擬地址空間,則對CPU而言,兩個進程使用了同樣的虛擬地址空間。快速上下文切換機構(gòu)對各進程的虛擬地址進行變換,這樣系統(tǒng)中除了CPU之外的部分看到的是經(jīng)過快速上下文切換機構(gòu)變換的虛擬地址。快速上下文切換機構(gòu)將各進程的虛擬空間變換成不同的虛擬空間,這樣在進行進程間切換時就不需要進行虛擬地址到物理地址的重映射。
快速上下文切換(FCSE)通過修改系統(tǒng)中不同進程的虛擬地址,避免在進行進程間切換時造成的虛擬地址到物理地址的重映射,這樣就減少了重建MMU、使cache和TLB無效、重建cache和TLB內(nèi)容等操作的巨大開銷,從而提高系統(tǒng)的性能。
5.3.2 FCSE原理
在ARM系統(tǒng)中,4GB的虛擬空間被分成128個進程空間塊,每個進程空間塊大小為32MB。每個進程空間塊中可以包含一個進程,該進程可以使用虛擬地址空間0x00000000~0x01ffffff,這個地址范圍也就是CPU看到的進程的虛擬空間。系統(tǒng)128個進程空間塊的編號為0~127,編號為 I的進程空間塊中的進程實際使用的虛擬地址空間為 I*0x02000000到 I*0x02000000+0x01ffffff,這個地址空間是系統(tǒng)中除了CPU之外的其他部分看到的該進程所占用的虛擬地址空間。
快速上下文切換機構(gòu)將CPU發(fā)出的每個虛擬地址按照上述的規(guī)則進行變換,然后發(fā)送到系統(tǒng)中的其他部分,變換過程如圖5-1所示。

圖5-1 FCSE原理框圖
圖5-1中地址VA到MVA的變換算法如下:
if (VA[31:25] == 0b0000000) then MVA = VA | (PID <<25) else MVA = VA
如果VA[31:25]不等于0,說明地址VA是本進程用于訪問其他進程中的數(shù)據(jù)和指令的虛擬地址,此時被訪問進程的PID不能為0。相反如果VA[31:25]等于0,說明要訪問的地址VA在該進程自身地址空間內(nèi),所以要進行進程上下文切換,將VA轉(zhuǎn)換成MVA,其中上面公式中的PID是該進程的PID號。
5.3.3 FCSE編程接口
ARM處理器用CP15協(xié)處理器的C13寄存器來實現(xiàn)FCSE功能,C13寄存器的介紹詳見第4.1.2節(jié)“CP15寄存器介紹”。當要進行進程切換時,首先清空寫緩存,再把新進程的頁表地址寫入CP15的C2寄存器,然后把新進程的PID號寫入CP15的C13寄存器的最高7位即可。如果處理器不支持FCSE功能,那么使cache和TLBs無效,然后系統(tǒng)要重建cache和TLBs。下面我們比較一下XScale處理器以及ARMv6處理器中進程切換中的內(nèi)存切換操作函數(shù)的區(qū)別:
XScale處理器進程切換中的內(nèi)存切換操作函數(shù)如下所示:
.align 5 ENTRY(cpu_xscale_switch_mm) clean_d_cache r1, r2;使r1所指地址到r2所指地址之間數(shù)據(jù)cache無效 mcr p15, 0, ip, c7, c5, 0;使系統(tǒng)全部指令cache無效 mcr p15, 0, ip, c7, c10, 4;清空寫緩存Write Buffer mcr p15, 0, r0, c2, c0, 0;裝入新的頁表地址 mcr p15, 0, ip, c8, c7, 0;使系統(tǒng)全部數(shù)據(jù)和指令TLBs cache無效 cpwait_ret lr, ip;返回
ARMv6處理器進程切換中的內(nèi)存切換操作函數(shù)如下所示:
ENTRY(cpu_v6_switch_mm) mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID];獲取新進程的PID號,該PID號其實就是新進程的 struct mm_struct結(jié)構(gòu)中的mm_context_t成員結(jié)構(gòu)context的id mcr p15, 0, r2, c7, c10, 4;清空寫緩存Write Buffer mcr p15, 0, r0, c2, c0, 0 ;裝入新的頁表地址 mcr p15, 0, r1, c13, c0, 1;設置上下文PID號 mov pc, lr;返回
在ARM處理器中只有ARMv6以上版本的處理器才支持FCSE功能。