偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

內(nèi)存加速的秘密武器:TLB緩存原理和應(yīng)用全解析

存儲(chǔ) 存儲(chǔ)架構(gòu)
緩存就像是一個(gè)數(shù)據(jù)的 “高速中轉(zhuǎn)站”,它位于 CPU 和內(nèi)存之間,存儲(chǔ)著 CPU 近期可能會(huì)頻繁訪問的數(shù)據(jù)。當(dāng) CPU 需要訪問數(shù)據(jù)時(shí),會(huì)首先在緩存中查找,如果能夠在緩存中找到所需的數(shù)據(jù),就可以直接從緩存中讀取,從而大大減少了內(nèi)存訪問的時(shí)間。緩存技術(shù)的出現(xiàn),在一定程度上緩解了內(nèi)存訪問延遲的問題,但它并沒有從根本上解決這一難題。

在計(jì)算機(jī)程序的運(yùn)行過程中,內(nèi)存訪問是一個(gè)極其基礎(chǔ)且關(guān)鍵的操作。程序的每一次數(shù)據(jù)讀取與寫入,都離不開內(nèi)存的支持。然而,內(nèi)存訪問延遲問題卻如同一只攔路虎,橫亙?cè)诔绦蚋咝н\(yùn)行的道路上。為了應(yīng)對(duì)內(nèi)存訪問延遲這一挑戰(zhàn),計(jì)算機(jī)科學(xué)家們可謂絞盡腦汁,提出了各種各樣的優(yōu)化策略和技術(shù)。緩存技術(shù)便是其中一種極為重要且廣泛應(yīng)用的手段。

緩存就像是一個(gè)數(shù)據(jù)的 “高速中轉(zhuǎn)站”,它位于 CPU 和內(nèi)存之間,存儲(chǔ)著 CPU 近期可能會(huì)頻繁訪問的數(shù)據(jù)。當(dāng) CPU 需要訪問數(shù)據(jù)時(shí),會(huì)首先在緩存中查找,如果能夠在緩存中找到所需的數(shù)據(jù),就可以直接從緩存中讀取,從而大大減少了內(nèi)存訪問的時(shí)間。緩存技術(shù)的出現(xiàn),在一定程度上緩解了內(nèi)存訪問延遲的問題,但它并沒有從根本上解決這一難題。

在緩存技術(shù)中,有一種特殊的緩存 ——TLB(Translation Lookaside Buffer)緩存,它在優(yōu)化內(nèi)存訪問效率方面發(fā)揮著舉足輕重的作用 。TLB 緩存主要用于存儲(chǔ)虛擬地址到物理地址的映射關(guān)系,能夠顯著加速地址轉(zhuǎn)換的過程。那么,TLB 緩存究竟是如何工作的?它的內(nèi)部結(jié)構(gòu)和工作原理又是怎樣的呢?在實(shí)際的應(yīng)用中,我們又該如何充分利用 TLB 緩存來提高內(nèi)存訪問效率呢?接下來,就讓我們一同深入探索 TLB 緩存的奧秘。

一、TLB緩存是什么?

TLB,即 Translation Lookaside Buffer,中文名為地址轉(zhuǎn)換后備緩沖器 ,是一種高速緩存,在內(nèi)存管理中扮演著關(guān)鍵角色。在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,為了更有效地管理內(nèi)存和提供內(nèi)存保護(hù),引入了虛擬內(nèi)存機(jī)制。在這種機(jī)制下,程序使用的是虛擬地址,而實(shí)際的數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中,這就需要進(jìn)行虛擬地址到物理地址的轉(zhuǎn)換。而TLB正是用于存儲(chǔ)虛擬地址到物理地址的映射關(guān)系,它就像是頁表的緩存。

頁表是存儲(chǔ)虛擬地址與物理地址映射關(guān)系的數(shù)據(jù)結(jié)構(gòu),通常存放在內(nèi)存中。由于內(nèi)存訪問速度相對(duì)較慢,如果每次地址轉(zhuǎn)換都要訪問內(nèi)存中的頁表,會(huì)極大地影響系統(tǒng)性能。而 TLB 作為頁表的緩存,存儲(chǔ)了近期最常訪問的頁表項(xiàng),當(dāng) CPU 需要進(jìn)行地址轉(zhuǎn)換時(shí),會(huì)首先在 TLB 中查找,從而大大提高了地址轉(zhuǎn)換的速度 。

一個(gè)程序是運(yùn)行在虛擬存儲(chǔ)器空間的,它的大小由處理器位數(shù)決定,對(duì)于一個(gè)32位處理器來說,其地址范圍就是0~0xFFFF FFFF,也就是4GB;而對(duì)于一個(gè)64位處理器,其地址范圍是0~0xFFFF FFFF FFFF FFFF,這個(gè)范圍就是程序能夠產(chǎn)生的地址范圍,其中的某一個(gè)地址就稱為虛擬地址。

和虛擬存儲(chǔ)器相對(duì)應(yīng)的就是物理存儲(chǔ)器,它是在現(xiàn)實(shí)世界中能直接使用的存儲(chǔ)器,其中的某一個(gè)地址就是物理地址。物理存儲(chǔ)器的大小不能夠超過處理器最大可以尋址的空間,例如,對(duì)于32位的x86 PC來說,它的物理存儲(chǔ)器(一般簡(jiǎn)稱為內(nèi)存)可以是256MB,即PM的范圍是0~0xFFF FFFF,當(dāng)然,也可以將物理內(nèi)存增加到4GB,此時(shí)虛擬存儲(chǔ)器和物理存儲(chǔ)器的地址空間的大小就是相同的。

使用了虛擬地址,則處理器輸出的地址就是虛擬地址,這個(gè)地址不會(huì)被直接送到物理存儲(chǔ)器中,而要先進(jìn)行地址轉(zhuǎn)換,因?yàn)樘摂M地址沒有辦法直接尋址物理存儲(chǔ)器,負(fù)責(zé)地址轉(zhuǎn)換的部件稱為內(nèi)存管理單元(Memory Manage Unit, MMU),如下圖所示。

圖片圖片

使用虛擬存儲(chǔ)器不僅便于程序在處理器中運(yùn)行,還給程序編寫帶來好處,在直接使用物理存儲(chǔ)器的處理器中,如果要同時(shí)運(yùn)行多個(gè)程序,需要為每個(gè)程序都分配一塊地址空間,每個(gè)程序都需要在這個(gè)地址空間內(nèi)運(yùn)行,這樣極大地限制了程序的編寫,而且不能夠使處理器隨便地運(yùn)行程序。

通過操作系統(tǒng)動(dòng)態(tài)地將每個(gè)程序的虛擬地址轉(zhuǎn)化為物理地址,還可以實(shí)現(xiàn)程序的保護(hù),即使兩個(gè)程序使用了同一個(gè)虛擬地址,它們也會(huì)對(duì)應(yīng)到不同的物理地址,因此可以保證每個(gè)程序的內(nèi)容不會(huì)被其他的程序隨便改寫。

而且通過這樣的方式,還可以實(shí)現(xiàn)程序間的共享,例如操作系統(tǒng)內(nèi)核提供了打印(printf)函數(shù),第一個(gè)程序在地址A使用了printf函數(shù),第二個(gè)程序在地址B使用了printf函數(shù),操作系統(tǒng)在地址轉(zhuǎn)換的時(shí)候,會(huì)將地址A和B都轉(zhuǎn)換為同樣的物理地址,這個(gè)物理地址就是printf函數(shù)在物理存儲(chǔ)器中的實(shí)際地址,這樣就實(shí)現(xiàn)了程序的共享,雖然兩個(gè)程序都使用了printf函數(shù),但是沒必要使printf函數(shù)占用物理存儲(chǔ)器的兩個(gè)地方,因此,使用虛擬存儲(chǔ)器不僅可以降低物理存儲(chǔ)器的容量需求,還可以帶來另外的好處,如保護(hù)(protect)和共享(share)。

一個(gè)處理器要支持現(xiàn)代的操作系統(tǒng),就必須支持虛擬存儲(chǔ)器,它是操作系統(tǒng)一個(gè)非常重要的內(nèi)容。

二、地址轉(zhuǎn)換

目前最通用的虛擬存儲(chǔ)器實(shí)現(xiàn)方式是基于分頁(page)的虛擬存儲(chǔ)器。虛擬地址空間以頁為單位劃分,典型的頁大小為4KB,相應(yīng)的物理地址空間也進(jìn)行同樣大小的劃分,由于歷史原因,在物理地址空間中不叫做頁,而稱為frame,它和頁的大小必須相等。當(dāng)程序開始運(yùn)行時(shí),會(huì)將當(dāng)前需要的部分內(nèi)容從硬盤中搬移到物理內(nèi)存中,每次搬移的單位就是一個(gè)頁的大小。由于只有在需要的時(shí)候才將一個(gè)頁的內(nèi)容放到物理內(nèi)存中,這種方式就稱為demand page,它是處理器可以運(yùn)行比物理內(nèi)存更大的程序。

對(duì)于一個(gè)虛擬地址(Virtual Address)來說,VA[11:0]表示頁內(nèi)的位置,稱為page offset,VA剩余的部分用來表示哪個(gè)頁,也稱為VPN(Virtual Page Number)。相應(yīng)的,對(duì)于一個(gè)物理地址PA(Physical Address)來說,PA[11:0]表示frame內(nèi)的位置,稱為frame offset,而PA剩余的部分用來表示哪個(gè)frame,也稱為PFN(Physical Frame Number)。由于頁和frame的大小是一樣的,所以從VA到PA的轉(zhuǎn)化實(shí)際上也就是從VPN到PFN的轉(zhuǎn)化,offset的部分是不需要變化的。

2.1 單級(jí)頁表

在使用虛擬存儲(chǔ)器的系統(tǒng)中,都是使用一張表格來存儲(chǔ)從虛擬地址到物理地址(實(shí)際上是VPN到PFN)的對(duì)應(yīng)關(guān)系,這個(gè)表格稱為頁表(Page Table,PT),也稱為轉(zhuǎn)換表(translation table)。這個(gè)表格一般是放在物理內(nèi)存中,使用虛擬地址來尋址,表格中被尋址到的內(nèi)容就是這個(gè)虛擬地址對(duì)應(yīng)的物理地址。

每個(gè)程序都有自己的頁表,用來將這個(gè)程序中的虛擬地址映射到物理內(nèi)存中的某個(gè)地址,為了指示一個(gè)程序的頁表在物理內(nèi)存中的位置,在處理器中一般都會(huì)包括一個(gè)寄存器,用來存放當(dāng)前運(yùn)行程序的頁表在物理內(nèi)存中的起始地址,這個(gè)寄存器稱為頁表寄存器(Page Table Register,PTR),每次操作系統(tǒng)將一個(gè)程序調(diào)入物理內(nèi)存中執(zhí)行的時(shí)候,就會(huì)將寄存器PTR設(shè)置好,當(dāng)然,上面的這種機(jī)制可以工作的前提是頁表位于物理內(nèi)存中一片連續(xù)的地址空間內(nèi)。

下圖表示了如何使用PTR從物理內(nèi)存中定位到一個(gè)頁表,并使用虛擬地址來尋址頁表,從而找到對(duì)應(yīng)的物理地址的過程。其實(shí),使用PTR和虛擬地址共同來尋址頁表,這就相當(dāng)于使用它們兩個(gè)共同組成一個(gè)地址,使用這個(gè)地址來尋址物理內(nèi)存。圖中仍然假設(shè)每個(gè)頁的大小是4KB,使用PTR和虛擬地址共同來尋址頁表,找到對(duì)應(yīng)的表項(xiàng)(entry),當(dāng)這個(gè)表項(xiàng)對(duì)應(yīng)的有效位(valid)為1時(shí),就表示這個(gè)虛擬地址所在的4KB空間已經(jīng)被操作系統(tǒng)映射到了物理內(nèi)存中,可以直接從物理內(nèi)存中找到這個(gè)虛擬地址對(duì)應(yīng)的數(shù)據(jù),其實(shí),這時(shí)候訪問當(dāng)前頁內(nèi)任意的地址,就是訪問物理內(nèi)存中被映射的那個(gè)4KB的空間了。

相反,如果頁表中這個(gè)被尋址的表項(xiàng)的有效位是0,則表示這個(gè)虛擬地址對(duì)應(yīng)的4KB空間還沒有被操作系統(tǒng)映射到物理內(nèi)存中,此時(shí)就產(chǎn)生了Page Fault類型的異常,需要操作系統(tǒng)從更下一級(jí)的存儲(chǔ)器(例如硬盤或閃存)將這個(gè)頁對(duì)應(yīng)的4KB內(nèi)容搬移到物理內(nèi)存中。

圖片圖片

圖中使用了32位的虛擬地址,頁表在物理內(nèi)存中的起始地址用PTR來指示。虛擬地址的尋址空間是2^32字節(jié),也就是4GB;物理地址的尋址空間是2^30字節(jié),也就是1GB,這對(duì)應(yīng)著實(shí)際物理地址的尋址空間。在頁表中的一個(gè)表項(xiàng)(entry)能夠映射4KB的大小,為了能夠映射整個(gè)4GB的空間,需要表項(xiàng)的個(gè)數(shù)應(yīng)該是4GB/4KB=1M,也就是2^20,因此需要20位來尋址。也就是說32位的虛擬地址分成兩部分,低12bit用來尋址一個(gè)頁內(nèi)的內(nèi)容,高20bit用來尋址哪個(gè)頁,因此真正尋址頁表只需要VPN就夠了。從頁表中找到的內(nèi)容也不是整個(gè)物理地址,而只是PFN。

需要注意的是,頁表的結(jié)構(gòu)是不同于cache的,在頁表中包括了所有VPN的映射關(guān)系,所以可以直接使用VPN對(duì)頁表進(jìn)行尋址,而不需要使用Tag。

可以采用很多方法來減少一個(gè)進(jìn)程的頁表對(duì)于存儲(chǔ)空間的需求,最常用的是多級(jí)頁表(Hierarchical Page Table),這種方法可以減少頁表對(duì)于物理存儲(chǔ)空間的占用,而且非常容易使用硬件實(shí)現(xiàn),與之對(duì)應(yīng)的,本節(jié)所講述的頁表就稱為單級(jí)頁表(Single Page Table),也被稱為線性頁表(Linear Page Table)。

2.2 多級(jí)頁表

將一個(gè)4MB的線性頁表劃分為若干個(gè)更小的頁表,稱它們?yōu)樽禹摫?,處理器在?zhí)行進(jìn)程的時(shí)候,不需要一下子把整個(gè)線性頁表都放入物理內(nèi)存中,而是根據(jù)需求逐步地放入這些子頁表。而且,這些子頁表不需要占用連續(xù)的物理內(nèi)存空間。也就是說,相鄰的子頁表可以放在物理內(nèi)存中不連續(xù)的位置,這樣也提高了物理內(nèi)存的利用效率。但是,由于所有的子頁表是不連續(xù)地放在物理內(nèi)存中,所以依舊需要一個(gè)表格,來記錄每個(gè)子頁表在物理內(nèi)存中存儲(chǔ)的位置,稱這個(gè)表格為第一級(jí)頁表(Level1 Page Table),而那些子頁表為第二級(jí)頁表(Level2 Page Table)。

圖片圖片

這樣,要得到一個(gè)虛擬地址對(duì)應(yīng)的數(shù)據(jù),首先訪問第一級(jí)頁表,得到第二級(jí)頁表的基地址,然后再去第二級(jí)頁表才可以得到這個(gè)虛擬地址對(duì)應(yīng)的物理地址,然后就可以在物理內(nèi)存中取出相應(yīng)的數(shù)據(jù)了。

例如,對(duì)于一個(gè)32位虛擬地址、頁大小為4KB的系統(tǒng)來說,如果采用線性頁表,則頁表中表項(xiàng)個(gè)數(shù)為2^20,將其等分為2^10等份,每個(gè)等份就是一個(gè)第二級(jí)頁表,共有1024個(gè)第二級(jí)頁表,對(duì)應(yīng)著第一級(jí)頁表的1024個(gè)表項(xiàng)。也就是說,第一級(jí)頁表需要10位地址來進(jìn)行尋址。每個(gè)二級(jí)頁表中,表項(xiàng)個(gè)數(shù)為1024,也需要10位地址來尋址。

下圖中,一個(gè)頁表中的表項(xiàng)簡(jiǎn)稱為PTE,當(dāng)操作系統(tǒng)創(chuàng)建一個(gè)進(jìn)程時(shí),就在物理內(nèi)存中為這個(gè)進(jìn)程找到一個(gè)連續(xù)的4KB空間,存在這個(gè)進(jìn)程的第一級(jí)頁表,并且將第一級(jí)頁表在物理內(nèi)存中起始地址放到PTR寄存器中,在ARM是TTB寄存器,X86是CR3寄存器等。隨著這個(gè)進(jìn)程的進(jìn)行,操作系統(tǒng)會(huì)逐步在物理內(nèi)存中創(chuàng)建第二級(jí)頁表,每次創(chuàng)建一個(gè)第二級(jí)頁表,操作系統(tǒng)就要將它的起始地址放到第一級(jí)頁表對(duì)應(yīng)的表項(xiàng)中。

圖片圖片

在很多硬件實(shí)現(xiàn)Page Table Walk的處理器中,都采用了多級(jí)頁表的結(jié)構(gòu)。Page Table Walk是指當(dāng)發(fā)生TLB缺失時(shí),需要從頁表中找到對(duì)應(yīng)的映射關(guān)系并將其寫回到TLB的過程。

使用這種多級(jí)頁表結(jié)構(gòu),每一級(jí)的頁表都需要存儲(chǔ)在物理內(nèi)存中,因此要得到一個(gè)虛擬地址對(duì)應(yīng)的數(shù)據(jù),需要多次訪問物理內(nèi)存。顯然,這個(gè)過程消耗的時(shí)間是很長(zhǎng)。對(duì)于一個(gè)二級(jí)頁表,需要訪問兩次物理內(nèi)存,才能得到虛擬地址對(duì)應(yīng)的物理地址,然后還需要訪問一次物理內(nèi)存得到數(shù)據(jù),因此要得到虛擬地址對(duì)應(yīng)的數(shù)據(jù),共需要訪問三次物理內(nèi)存。

使用虛擬存儲(chǔ)器的優(yōu)點(diǎn)總結(jié):

(1)讓每個(gè)程序都有獨(dú)立的地址空間。

(2)引入虛擬地址到物理地址的映射,為物理內(nèi)存的管理帶來了方便,可以更靈活地對(duì)其進(jìn)行分配和釋放,在虛擬存儲(chǔ)器上連續(xù)的地址空間可以映射到物理內(nèi)存上不連續(xù)的空間。

(3)在處理中如果存在多個(gè)進(jìn)程,為這些進(jìn)程分配的物理內(nèi)存之和可能大于實(shí)際可用的物理內(nèi)存,虛擬存儲(chǔ)器的管理使得這種情況下各個(gè)進(jìn)程仍能夠正常運(yùn)行,此時(shí)為各個(gè)進(jìn)程分配的只是虛擬存儲(chǔ)器的頁,這些頁可能存在物理內(nèi)存中,也可能臨時(shí)存在于更下一級(jí)的硬盤中,在硬盤中這部分空間被稱為swap空間。當(dāng)物理內(nèi)存不夠用時(shí),將物理內(nèi)存中一些不常用的頁保存到硬盤上的swap空間。因此處理器等效可以使用的物理內(nèi)存的總量是物理內(nèi)存的大小 + 硬盤中swap空間的大小。

(4)利用虛擬存儲(chǔ)器,可以管理每一個(gè)頁的訪問權(quán)限。從硬件的角度來看,單純的物理內(nèi)存本身不具有各種權(quán)限的屬性,它的任何地址都可以被讀寫,而操作系統(tǒng)則要求在物理內(nèi)存中實(shí)現(xiàn)不同的訪問權(quán)限。例如一個(gè)進(jìn)程的代碼段(text)一般不能被修改,而數(shù)據(jù)段(data)一般是可讀可寫的。這些權(quán)限的管理是通過頁表來實(shí)現(xiàn)的,在頁表中設(shè)置每個(gè)頁的屬性,操作系統(tǒng)和內(nèi)存管理單元MMU可以控制每個(gè)頁的訪問權(quán)限。

三、TLB工作原理

首先,我們知道MMU的作用是把虛擬地址轉(zhuǎn)換成物理地址。虛擬地址和物理地址的映射關(guān)系存儲(chǔ)在頁表中,而現(xiàn)在頁表又是分級(jí)的。64位系統(tǒng)一般都是3~5級(jí)。常見的配置是4級(jí)頁表,就以4級(jí)頁表為例說明。分別是PGD、PUD、PMD、PTE四級(jí)頁表。在硬件上會(huì)有一個(gè)叫做頁表基地址寄存器,它存儲(chǔ)PGD頁表的首地址。MMU就是根據(jù)頁表基地址寄存器從PGD頁表一路查到PTE,最終找到物理地址(PTE頁表中存儲(chǔ)物理地址)。

這就像在地圖上顯示你的家在哪一樣,我為了找到你家的地址,先確定你是中國,再確定你是某個(gè)省,繼續(xù)往下某個(gè)市,最后找到你家是一樣的原理。一級(jí)一級(jí)找下去。這個(gè)過程你也看到了,非常繁瑣。如果第一次查到你家的具體位置,我如果記下來你的姓名和你家的地址。下次查找時(shí),是不是只需要跟我說你的姓名是什么,我就直接能夠告訴你地址,而不需要一級(jí)一級(jí)查找。四級(jí)頁表查找過程需要四次內(nèi)存訪問。延時(shí)可想而知,非常影響性能。

3.1地址轉(zhuǎn)換流程

當(dāng) CPU 訪問內(nèi)存時(shí),首先會(huì)生成一個(gè)虛擬地址,這個(gè)虛擬地址會(huì)被發(fā)送到 TLB 中進(jìn)行查找。如果 TLB 中存儲(chǔ)了該虛擬地址對(duì)應(yīng)的物理地址,這就是所謂的 “TLB 命中”。此時(shí),CPU 可以直接從 TLB 中獲取物理地址,并使用該物理地址去訪問內(nèi)存,這大大縮短了內(nèi)存訪問的時(shí)間。

圖片圖片

但如果 TLB 中沒有找到對(duì)應(yīng)的映射關(guān)系,即發(fā)生了 “TLB 缺失”,CPU 就需要訪問內(nèi)存中的頁表。頁表通常是多級(jí)結(jié)構(gòu),以 x86 架構(gòu)的 4 級(jí)頁表為例,CPU 需要從頁表基地址寄存器開始,一級(jí)一級(jí)地查找,通過索引找到下一級(jí)頁表的物理地址,最終找到包含虛擬地址到物理地址映射關(guān)系的頁表項(xiàng),獲取物理地址。這個(gè)過程需要多次訪問內(nèi)存,非常耗時(shí)。

在通過頁表獲取到物理地址后,CPU 會(huì)將這次的虛擬地址到物理地址的映射關(guān)系存入 TLB 中,以便下次訪問相同虛擬地址時(shí)能夠直接在 TLB 中命中,提高訪問效率。

3.2TLB原理

當(dāng)cpu要訪問一個(gè)虛擬地址/線性地址時(shí),CPU會(huì)首先根據(jù)虛擬地址的高20位(20是x86特定的,不同架構(gòu)有不同的值)在TLB中查找。如果是表中沒有相應(yīng)的表項(xiàng),稱為TLB miss,需要通過訪問慢速RAM中的頁表計(jì)算出相應(yīng)的物理地址。同時(shí),物理地址被存放在一個(gè)TLB表項(xiàng)中,以后對(duì)同一線性地址的訪問,直接從TLB表項(xiàng)中獲取物理地址即可,稱為TLB hit。

想像一下x86_32架構(gòu)下沒有TLB的存在時(shí)的情況,對(duì)線性地址的訪問,首先從PGD中獲取PTE(第一次內(nèi)存訪問),在PTE中獲取頁框地址(第二次內(nèi)存訪問),最后訪問物理地址,總共需要3次RAM的訪問。如果有TLB存在,并且TLB hit,那么只需要一次RAM訪問即可。

⑴TLB的特殊

虛擬地址映射物理地址的最小單位是4KB。所以TLB其實(shí)不需要存儲(chǔ)虛擬地址和物理地址的低12位(因?yàn)榈?2位是一樣的,根本沒必要存儲(chǔ))。另外,我們?nèi)绻衏ache,肯定是一次性從cache中拿出整個(gè)數(shù)據(jù)。所以虛擬地址不需要offset域。index域是否需要呢?這取決于cache的組織形式。如果是全相連高速緩存。那么就不需要index。如果使用多路組相連高速緩存,依然需要index。下圖就是一個(gè)四路組相連TLB的例子。現(xiàn)如今64位CPU尋址范圍并沒有擴(kuò)大到64位。64位地址空間很大,現(xiàn)如今還用不到那么大。因此硬件為了設(shè)計(jì)簡(jiǎn)單或者解決成本,實(shí)際虛擬地址位數(shù)只使用了一部分。這里以48位地址總線為了例說明。

圖片圖片

⑵TLB的別名問題

我先來思考第一個(gè)問題,別名是否存在。我們知道PIPT的數(shù)據(jù)cache不存在別名問題。物理地址是唯一的,一個(gè)物理地址一定對(duì)應(yīng)一個(gè)數(shù)據(jù)。但是不同的物理地址可能存儲(chǔ)相同的數(shù)據(jù)。也就是說,物理地址對(duì)應(yīng)數(shù)據(jù)是一對(duì)一關(guān)系,反過來是多對(duì)一關(guān)系。由于TLB的特殊性,存儲(chǔ)的是虛擬地址和物理地址的對(duì)應(yīng)關(guān)系。

因此,對(duì)于單個(gè)進(jìn)程來說,同一時(shí)間一個(gè)虛擬地址對(duì)應(yīng)一個(gè)物理地址,一個(gè)物理地址可以被多個(gè)虛擬地址映射。將PIPT數(shù)據(jù)cache類比TLB,我們可以知道TLB不存在別名問題。而VIVT Cache存在別名問題,原因是VA需要轉(zhuǎn)換成PA,PA里面才存儲(chǔ)著數(shù)據(jù)。中間多經(jīng)傳一手,所以引入了些問題。

⑶TLB的歧義問題

我們知道不同的進(jìn)程之間看到的虛擬地址范圍是一樣的,所以多個(gè)進(jìn)程下,不同進(jìn)程的相同的虛擬地址可以映射不同的物理地址。這就會(huì)造成歧義問題。例如,進(jìn)程A將地址0x2000映射物理地址0x4000。進(jìn)程B將地址0x2000映射物理地0x5000。

當(dāng)進(jìn)程A執(zhí)行的時(shí)候?qū)?x2000對(duì)應(yīng)0x4000的映射關(guān)系緩存到TLB中。當(dāng)切換B進(jìn)程的時(shí)候,B進(jìn)程訪問0x2000的數(shù)據(jù),會(huì)由于命中TLB從物理地址0x4000取數(shù)據(jù)。這就造成了歧義。如何消除這種歧義,我們可以借鑒VIVT數(shù)據(jù)cache的處理方式,在進(jìn)程切換時(shí)將整個(gè)TLB無效。切換后的進(jìn)程都不會(huì)命中TLB,但是會(huì)導(dǎo)致性能損失。

⑷TLB表項(xiàng)

TLB內(nèi)部存放的基本單位是頁表?xiàng)l目,對(duì)應(yīng)著RAM中存放的頁表?xiàng)l目。頁表?xiàng)l目的大小固定不變的,所以TLB容量越大,所能存放的頁表?xiàng)l目越多,TLB hit的幾率也越大。但是TLB容量畢竟是有限的,因此RAM頁表和TLB頁表?xiàng)l目無法做到一一對(duì)應(yīng)。因此CPU收到一個(gè)線性地址,那么必須快速做兩個(gè)判斷:

  • 所需的也表示否已經(jīng)緩存在TLB內(nèi)部(TLB miss或者TLB hit)
  • 所需的頁表在TLB的哪個(gè)條目?jī)?nèi)

為了盡量減少CPU做出這些判斷所需的時(shí)間,那么就必須在TLB頁表?xiàng)l目和內(nèi)存頁表?xiàng)l目之間的對(duì)應(yīng)方式做足功夫。

⑸全相連 - full associative

在這種組織方式下,TLB cache中的表項(xiàng)和線性地址之間沒有任何關(guān)系,也就是說,一個(gè)TLB表項(xiàng)可以和任意線性地址的頁表項(xiàng)關(guān)聯(lián)。這種關(guān)聯(lián)方式使得TLB表項(xiàng)空間的利用率最大。但是延遲也可能相當(dāng)?shù)拇螅驗(yàn)槊看蜟PU請(qǐng)求,TLB硬件都把線性地址和TLB的表項(xiàng)逐一比較,直到TLB hit或者所有TLB表項(xiàng)比較完成。特別是隨著CPU緩存越來越大,需要比較大量的TLB表項(xiàng),所以這種組織方式只適合小容量TLB。

⑹直接匹配

每一個(gè)線性地址塊都可通過模運(yùn)算對(duì)應(yīng)到唯一的TLB表項(xiàng),這樣只需進(jìn)行一次比較,降低了TLB內(nèi)比較的延遲。但是這個(gè)方式產(chǎn)生沖突的幾率非常高,導(dǎo)致TLB miss的發(fā)生,降低了命中率。

比如,我們假定TLB cache共包含16個(gè)表項(xiàng),CPU順序訪問以下線性地址塊:1, 17 , 1, 33。當(dāng)CPU訪問地址塊1時(shí),1 mod 16 = 1,TLB查看它的第一個(gè)頁表項(xiàng)是否包含指定的線性地址塊1,包含則命中,否則從RAM裝入;然后CPU方位地址塊17,17 mod 16 = 1,TLB發(fā)現(xiàn)它的第一個(gè)頁表項(xiàng)對(duì)應(yīng)的不是線性地址塊17,TLB miss發(fā)生,TLB訪問RAM把地址塊17的頁表項(xiàng)裝入TLB;CPU接下來訪問地址塊1,此時(shí)又發(fā)生了miss,TLB只好訪問RAM重新裝入地址塊1對(duì)應(yīng)的頁表項(xiàng)。因此在某些特定訪問模式下,直接匹配的性能差到了極點(diǎn)

⑺組相連 - set-associative

為了解決全相連內(nèi)部比較效率低和直接匹配的沖突,引入了組相連。這種方式把所有的TLB表項(xiàng)分成多個(gè)組,每個(gè)線性地址塊對(duì)應(yīng)的不再是一個(gè)TLB表項(xiàng),而是一個(gè)TLB表項(xiàng)組。CPU做地址轉(zhuǎn)換時(shí),首先計(jì)算線性地址塊對(duì)應(yīng)哪個(gè)TLB表項(xiàng)組,然后在這個(gè)TLB表項(xiàng)組順序比對(duì)。按照組長(zhǎng)度,我們可以稱之為2路,4路,8路。

經(jīng)過長(zhǎng)期的工程實(shí)踐,發(fā)現(xiàn)8路組相連是一個(gè)性能分界點(diǎn)。8路組相連的命中率幾乎和全相連命中率幾乎一樣,超過8路,組內(nèi)對(duì)比延遲帶來的缺點(diǎn)就超過命中率提高帶來的好處了。

這三種方式各有優(yōu)缺點(diǎn),組相連是個(gè)折衷的選擇,適合大部分應(yīng)用環(huán)境。當(dāng)然針對(duì)不同的領(lǐng)域,也可以采用其他的cache組織形式。

⑻LB表項(xiàng)更新

TLB表項(xiàng)更新可以有TLB硬件自動(dòng)發(fā)起,也可以有軟件主動(dòng)更新

1. TLB miss發(fā)生后,CPU從RAM獲取頁表項(xiàng),會(huì)自動(dòng)更新TLB表項(xiàng)

2. TLB中的表項(xiàng)在某些情況下是無效的,比如進(jìn)程切換,更改內(nèi)核頁表等,此時(shí)CPU硬件不知道哪些TLB表項(xiàng)是無效的,只能由軟件在這些場(chǎng)景下,刷新TLB。

在linux kernel軟件層,提供了豐富的TLB表項(xiàng)刷新方法,但是不同的體系結(jié)構(gòu)提供的硬件接口不同。比如x86_32僅提供了兩種硬件接口來刷新TLB表項(xiàng):

1. 向cr3寄存器寫入值時(shí),會(huì)導(dǎo)致處理器自動(dòng)刷新非全局頁的TLB表項(xiàng)

2. 在Pentium Pro以后,invlpg匯編指令用來無效指定線性地址的單個(gè)TLB表項(xiàng)無效。

3.3映射方式剖析

虛地址與 TLB 中項(xiàng)的映射方式主要有以下三種:

全關(guān)聯(lián)映射:在全關(guān)聯(lián)映射方式下,TLB 中的任何一個(gè)表項(xiàng)都可以存儲(chǔ)任何虛擬地址的映射關(guān)系。這種映射方式的優(yōu)點(diǎn)是靈活性高,TLB 表項(xiàng)空間的利用率最大,只要 TLB 中還有空閑表項(xiàng),就可以存儲(chǔ)新的映射關(guān)系 。但缺點(diǎn)也很明顯,每次查找時(shí),TLB 硬件都需要把虛擬地址和 TLB 中的所有表項(xiàng)逐一進(jìn)行比較,直到找到匹配的表項(xiàng)或者所有表項(xiàng)都比較完。

隨著 CPU 緩存越來越大,TLB 中的表項(xiàng)數(shù)量也可能增多,這種比較操作的延遲會(huì)相當(dāng)大,所以全關(guān)聯(lián)映射方式只適合小容量的 TLB。例如,一個(gè)只有 8 個(gè)表項(xiàng)的小容量 TLB,采用全關(guān)聯(lián)映射時(shí),雖然查找時(shí)需要逐個(gè)比較,但由于表項(xiàng)數(shù)量少,延遲還在可接受范圍內(nèi),且能充分利用表項(xiàng)空間。

直接映射:直接映射方式是指每一個(gè)虛擬地址只能映射到 TLB 中唯一的一個(gè)表項(xiàng)。這種映射方式的優(yōu)點(diǎn)是查找速度快,只需進(jìn)行一次比較。例如,假設(shè)內(nèi)存頁大小是 8KB,TLB 中有 64 項(xiàng),虛擬地址的 13 - 18bit 作為 TLB 表項(xiàng)的索引。當(dāng)虛擬地址的 13 - 18bit 確定后,就可以直接定位到 TLB 中的某一個(gè)表項(xiàng)進(jìn)行比較。但直接映射方式產(chǎn)生沖突的幾率非常高,導(dǎo)致 TLB miss 的發(fā)生,降低了命中率。比如,CPU 順序訪問線性地址塊 1 和 17,由于 1 mod 64 和 17 mod 64 得到的索引相同,當(dāng)訪問完 1 后再訪問 17 時(shí),就會(huì)發(fā)生沖突,導(dǎo)致 TLB miss,需要重新從內(nèi)存中加載頁表項(xiàng)。

分組關(guān)聯(lián)映射:分組關(guān)聯(lián)映射方式結(jié)合了全關(guān)聯(lián)映射和直接映射的優(yōu)點(diǎn),它把 TLB 中的所有表項(xiàng)分成多個(gè)組,每個(gè)虛擬地址對(duì)應(yīng)的不再是一個(gè) TLB 表項(xiàng),而是一個(gè) TLB 表項(xiàng)組。CPU 進(jìn)行地址轉(zhuǎn)換時(shí),首先計(jì)算虛擬地址對(duì)應(yīng)哪個(gè) TLB 表項(xiàng)組,然后在這個(gè)組內(nèi)順序比對(duì)。按照組長(zhǎng)度,可以分為 2 路、4 路、8 路等。經(jīng)過長(zhǎng)期的工程實(shí)踐發(fā)現(xiàn),8 路組關(guān)聯(lián)是一個(gè)性能分界點(diǎn),8 路組關(guān)聯(lián)的命中率幾乎和全關(guān)聯(lián)命中率一樣,超過 8 路,組內(nèi)對(duì)比延遲帶來的缺點(diǎn)就會(huì)超過命中率提高帶來的好處 。例如,采用 4 路組關(guān)聯(lián)時(shí),將 TLB 表項(xiàng)分為多個(gè) 4 個(gè)表項(xiàng)一組的組,虛擬地址通過計(jì)算索引確定對(duì)應(yīng)的組,然后在組內(nèi) 4 個(gè)表項(xiàng)中查找,這樣既減少了沖突的發(fā)生,又在一定程度上控制了查找延遲。

四、TLB緩存機(jī)制

4.1MMU

MMU:memory management unit,稱為內(nèi)存管理單元,或者是存儲(chǔ)器管理單元,MMU是硬件設(shè)備,它被保存在主存(main memory)的兩級(jí)也表控制,并且是由協(xié)處理器CP15的寄存器1的M位來決定是enabled還是disabled。MMU的主要作用是負(fù)責(zé)從CPU內(nèi)核發(fā)出的虛擬地址到物理地址的映射,并提供硬件機(jī)制的內(nèi)存訪問權(quán)限檢查。

MMU使得每個(gè)用戶進(jìn)程擁有自己的地址空間(對(duì)于WINCE5.0,每個(gè)進(jìn)程是32MB;而對(duì)于WINCE6.0,每個(gè)進(jìn)程的獨(dú)占的虛擬空間是2GB),并通過內(nèi)存訪問權(quán)限的檢查保護(hù)每個(gè)進(jìn)程所用的內(nèi)存不被其他進(jìn)程破壞,它提供了以下功能和特征:

  • 虛擬內(nèi)存管理:MMU將程序使用的虛擬地址轉(zhuǎn)換為物理地址,實(shí)現(xiàn)了對(duì)虛擬內(nèi)存空間的管理。它允許每個(gè)程序有自己獨(dú)立的地址空間,并且可以在不同程序之間共享物理內(nèi)存。
  • 地址映射:MMU通過頁表或段表來實(shí)現(xiàn)虛擬地址到物理地址的映射。它根據(jù)頁表或段表中的映射規(guī)則,將虛擬地址轉(zhuǎn)換為對(duì)應(yīng)的物理地址。
  • 內(nèi)存保護(hù):MMU可以設(shè)置頁面級(jí)別或段級(jí)別的權(quán)限控制,以保護(hù)操作系統(tǒng)和應(yīng)用程序不被非法訪問。例如,可以限制某些頁面只讀、只執(zhí)行或禁止訪問。
  • 虛擬化支持:在虛擬化環(huán)境中,MMU可以實(shí)現(xiàn)虛擬機(jī)與物理機(jī)之間的隔離和映射。
  • 緩存控制:MMU可以進(jìn)行緩存一致性控制,確保數(shù)據(jù)在主存與緩存之間的一致性。
  • TLB(Translation Lookaside Buffer):MMU通常會(huì)包含一個(gè)TLB,用于緩存最近的地址映射結(jié)果,以加速地址轉(zhuǎn)換過程。

(1)VA和PA

VA(Virtual Address)是程序在運(yùn)行時(shí)使用的虛擬地址。它由MMU(Memory Management Unit,內(nèi)存管理單元)根據(jù)頁表或段表的映射規(guī)則進(jìn)行轉(zhuǎn)換,將其映射為對(duì)應(yīng)的PA。

PA(Physical Address)是實(shí)際存在于物理內(nèi)存中的物理地址。它指向計(jì)算機(jī)硬件中實(shí)際存儲(chǔ)單元的位置。

通過使用虛擬內(nèi)存管理技術(shù),操作系統(tǒng)將程序使用的虛擬地址空間與物理內(nèi)存進(jìn)行映射。這樣,每個(gè)程序都有自己獨(dú)立的虛擬地址空間,而不需要關(guān)心真正分配給它們的物理內(nèi)存位置。

當(dāng)程序訪問某個(gè)虛擬地址時(shí),MMU會(huì)將其轉(zhuǎn)換為對(duì)應(yīng)的物理地址,并且確保訪問權(quán)限合法。這樣,程序可以以統(tǒng)一的方式訪問內(nèi)存,并且操作系統(tǒng)可以更好地管理和保護(hù)整個(gè)系統(tǒng)中的內(nèi)存資源。

CPU通過地址來訪問內(nèi)存中的單元,如果CPU沒有MMU,或者有MMU但沒有啟動(dòng),那么CPU內(nèi)核在取指令或者訪問內(nèi)存時(shí)發(fā)出的地址(此時(shí)必須是物理地址,假如是虛擬地址,那么當(dāng)前的動(dòng)作無效)將直接傳到CPU芯片的外部地址引腳上,直接被內(nèi)存芯片(物理內(nèi)存)接收,這時(shí)候的地址就是物理地址。

如果CPU啟用了MMU(一般是在bootloader中的eboot階段的進(jìn)入main()函數(shù)的時(shí)候啟用),CPU內(nèi)核發(fā)出的地址將被MMU截獲,這時(shí)候從CPU到MMU的地址稱為虛擬地址,而MMU將這個(gè)VA翻譯成為PA發(fā)到CPU芯片的外部地址引腳上,也就是將VA映射到PA中。

MMU將VA映射到PA是以頁(page)為單位的,對(duì)于32位的CPU,通常一頁為4k,物理內(nèi)存中的一個(gè)物理頁面稱頁為一個(gè)頁框(page frame)。虛擬地址空間劃分成稱為頁(page)的單位,而相應(yīng)的物理地址空間也被進(jìn)行劃分,單位是頁框(frame).頁和頁框的大小必須相同。

(2)VA到PA的映射過程

首先將CPU內(nèi)核發(fā)送過來的32位VA[31:0]分成三段,前兩段VA[31:20]和VA[19:12]作為兩次查表的索引,第三段VA[11:0]作為頁內(nèi)的偏移,查表的步驟如下:

  • ⑴從協(xié)處理器CP15的寄存器2(TTB寄存器,translation table base register)中取出保存在其中的第一級(jí)頁表(translation table)的基地址,這個(gè)基地址指的是PA,也就是說頁表是直接按照這個(gè)地址保存在物理內(nèi)存中的。
  • ⑵以TTB中的內(nèi)容為基地址,以VA[31:20]為索引值在一級(jí)頁表中查找出一項(xiàng)(2^12=4096項(xiàng)),這個(gè)頁表項(xiàng)(也稱為一個(gè)描述符,descriptor)保存著第二級(jí)頁表(coarse page table)的基地址,這同樣是物理地址,也就是說第二級(jí)頁表也是直接按這個(gè)地址存儲(chǔ)在物理內(nèi)存中的。
  • ⑶以VA[19:12]為索引值在第二級(jí)頁表中查出一項(xiàng)(2^8=256),這個(gè)表項(xiàng)中就保存著物理頁面的基地址,我們知道虛擬內(nèi)存管理是以頁為單位的,一個(gè)虛擬內(nèi)存的頁映射到一個(gè)物理內(nèi)存的頁框,從這里就可以得到印證,因?yàn)椴楸硎且皂摓閱挝粊聿榈摹?/span>
  • ⑷有了物理頁面的基地址之后,加上VA[11:0]這個(gè)偏移量(2^12=4KB)就可以取出相應(yīng)地址上的數(shù)據(jù)了。

這個(gè)過程稱為Translation Table Walk,Walk這個(gè)詞用得非常形象。從TTB走到一級(jí)頁表,又走到二級(jí)頁表,又走到物理頁面,一次尋址其實(shí)是三次訪問物理內(nèi)存。注意這個(gè)“走”的過程完全是硬件做的,每次CPU尋址時(shí)MMU就自動(dòng)完成以上四步,不需要編寫指令指示MMU去做,前提是操作系統(tǒng)要維護(hù)頁表項(xiàng)的正確性,每次分配內(nèi)存時(shí)填寫相應(yīng)的頁表項(xiàng),每次釋放內(nèi)存時(shí)清除相應(yīng)的頁表項(xiàng),在必要的時(shí)候分配或釋放整個(gè)頁表。

(3)CPU訪問內(nèi)存時(shí)的硬件操作順序

CPU訪問內(nèi)存時(shí)的硬件操作順序,各步驟在圖中有對(duì)應(yīng)的標(biāo)號(hào):

1.CPU內(nèi)核(圖中的ARM)發(fā)出VA請(qǐng)求讀數(shù)據(jù),TLB(translation lookaside buffer)接收到該地址,那為什么是TLB先接收到該地址呢?因?yàn)門LB是MMU中的一塊高速緩存(也是一種cache,是CPU內(nèi)核和物理內(nèi)存之間的cache),它緩存最近查找過的VA對(duì)應(yīng)的頁表項(xiàng),如果TLB里緩存了當(dāng)前VA的頁表項(xiàng)就不必做translation table walk了,否則就去物理內(nèi)存中讀出頁表項(xiàng)保存在TLB中,TLB緩存可以減少訪問物理內(nèi)存的次數(shù)。

2.頁表項(xiàng)中不僅保存著物理頁面的基地址,還保存著權(quán)限和是否允許cache的標(biāo)志。MMU首先檢查權(quán)限位,如果沒有訪問權(quán)限,就引發(fā)一個(gè)異常給CPU內(nèi)核。然后檢查是否允許cache,如果允許cache就啟動(dòng)cache和CPU內(nèi)核互操作。

3.如果不允許cache,那直接發(fā)出PA從物理內(nèi)存中讀取數(shù)據(jù)到CPU內(nèi)核。

4.如果允許cache,則以VA為索引到cache中查找是否緩存了要讀取的數(shù)據(jù)

如果cache中已經(jīng)緩存了該數(shù)據(jù)(稱為cache hit)則直接返回給CPU內(nèi)核,如果cache中沒有緩存該數(shù)據(jù)(稱為cache miss),則發(fā)出PA從物理內(nèi)存中讀取數(shù)據(jù)并緩存到cache中,同時(shí)返回給CPU內(nèi)核。但是cache并不是只去CPU內(nèi)核所需要的數(shù)據(jù),而是把相鄰的數(shù)據(jù)都去上來緩存,這稱為一個(gè)cache line。ARM920T的cache line是32個(gè)字節(jié),例如CPU內(nèi)核要讀取地址0x30000134~0x3000137的4個(gè)字節(jié)數(shù)據(jù),cache會(huì)把地址0x30000120~0x3000137(對(duì)齊到32字節(jié)地址邊界)的32字節(jié)都取上來緩存。

(4)ARM920T支持多種尺寸規(guī)格的頁表

ARM體系結(jié)構(gòu)最多使用兩級(jí)頁表來進(jìn)行轉(zhuǎn)換,頁表由一個(gè)個(gè)條目組成,每個(gè)條目存儲(chǔ)一段虛擬地址對(duì)應(yīng)的物理地址及訪問權(quán)限,或者下一級(jí)頁表的地址。S3C2443最多會(huì)用到兩級(jí)頁表,已段(section,大小為1M)的方式進(jìn)行轉(zhuǎn)換時(shí)只用到一級(jí)頁表,以頁(page)的方式進(jìn)行轉(zhuǎn)換時(shí)用到兩級(jí)頁表。而頁的大小有3種:大頁(large pages,64KB),小頁(small pages,4KB)和極小頁(tiny pages,1KB)。條目也成為描述符,有段描述符、大頁描述符、小頁描述符和極小頁描述符,分別保存段、大頁、小頁和極小頁的起始物理地址。

MMU的查表過程,首先從CP15的寄存器TTB找到一級(jí)頁表的基地址,再把VA[31:20]作為索引值從表中找出一項(xiàng),這個(gè)表項(xiàng)稱為一級(jí)頁描述符(level one descriptor),一個(gè)這樣的表項(xiàng)占4個(gè)字節(jié),那么一級(jí)頁表需要保存的物理內(nèi)存的大小是4*4096=16KB,表項(xiàng)可以是以下四種格式之一:

  • ⑴如果描述符的最低位是00,屬于fault格式,表示該范圍的VA沒有映射到PA。
  • ⑵如果描述符的最低位是10,屬于section格式,這種格式?jīng)]有二級(jí)頁表而是直接映射到物理頁面,一個(gè)色彩體哦你是1M的大頁面,描述符中的VA[31:20]就是這個(gè)頁面的基地址,基地址的VA[19:0]低位全為0,對(duì)齊到1M地址邊界,描述符中的domain和AP位控制訪問權(quán)限,C、B兩位控制緩存。
  • ⑶如果描述符的最低兩位是01或11,則分別對(duì)應(yīng)兩種不同規(guī)格的二級(jí)頁表。根據(jù)地址對(duì)齊的規(guī)律想一下,這兩種頁表分別是多大?從一級(jí)描述符中取出二級(jí)頁表的基地址,再把VA的一部分作為索引去查二級(jí)描述符(level two descriptor),如果是coarse page,則VA[19:12](2^8=256)作為查找二級(jí)頁表表項(xiàng)的索引;如果是fine page,則VA[19:10](2^10=024)。

(5)二級(jí)描述符可以是下面四種格式之一:

二級(jí)描述符最低兩位是00是屬于fault格式,其它三種情況分別對(duì)應(yīng)三種不同規(guī)格的物理頁面,分別是large page(64KB)、small page(4KB)和tiny page(1KB),其中l(wèi)arge page和small page有4組AP權(quán)限位,每組兩個(gè)bit,這樣可以為每1/4個(gè)物理頁面分別設(shè)置不同的權(quán)限,也就是說large page可以為每16KB設(shè)置不同的權(quán)限,small page可以為每1KB設(shè)置不同的權(quán)限。

ARM920T提供了多種頁表和頁面規(guī)格,但操作系統(tǒng)只采用其中一種,WINCE采用的就是一級(jí)描述符是coarse page table格式(也即由VA[19:12]來作為查找二級(jí)頁表項(xiàng)的索引),二級(jí)描述符是small page格式(也即是VA[11:0]來作為查找物理頁面偏移量的索引),每個(gè)物理頁面大小是4KB。

Translation table walk是指在虛擬地址轉(zhuǎn)換為物理地址的過程中,操作系統(tǒng)或硬件通過遍歷頁表或段表來完成地址映射的過程。

具體步驟如下:

  1. 獲取虛擬地址:首先,根據(jù)程序的執(zhí)行情況,獲取需要進(jìn)行地址轉(zhuǎn)換的虛擬地址。
  2. 訪問頁表(或段表)項(xiàng):根據(jù)操作系統(tǒng)或硬件的設(shè)計(jì),從頁表(或段表)中找到對(duì)應(yīng)的頁表項(xiàng)(或段描述符)。這一步通常涉及多級(jí)頁表結(jié)構(gòu)中的索引計(jì)算和查找。
  3. 檢查權(quán)限位:在訪問到頁表項(xiàng)(或段描述符)后,需要檢查相關(guān)權(quán)限位以確保訪問合法。比如讀寫執(zhí)行權(quán)限、特權(quán)級(jí)等。
  4. 轉(zhuǎn)換為物理地址:如果權(quán)限檢查通過,則根據(jù)頁表項(xiàng)中存儲(chǔ)的物理頁面框號(hào)或段基址與虛擬地址中的偏移量進(jìn)行計(jì)算,得到相應(yīng)的物理地址。
  5. 返回結(jié)果:將最終得到的物理地址返回給CPU或其他需要使用該地址的部件,使其能夠正確地訪問所需數(shù)據(jù)。

這個(gè)過程可以由操作系統(tǒng)內(nèi)核中的內(nèi)存管理單元(MMU)硬件自動(dòng)完成,也可以由軟件實(shí)現(xiàn)。不同操作系統(tǒng)和處理器架構(gòu)可能會(huì)有不同實(shí)現(xiàn)方式和細(xì)節(jié)。但總體思路是通過頁表或段表的遍歷,將虛擬地址轉(zhuǎn)換為物理地址,以實(shí)現(xiàn)內(nèi)存訪問的正確性和安全性。

4.2 Cache的設(shè)計(jì)

TLB只是加速了虛擬地址到物理地址的轉(zhuǎn)換,可以很快地得到所需要的數(shù)據(jù)或指令在物理內(nèi)存中的位置,也就是得到了物理地址,但如果直接從物理內(nèi)存中取數(shù)據(jù)或指令,顯然也是很慢的。因此可以用Cache來緩存物理地址到數(shù)據(jù)的轉(zhuǎn)換過程。這種Cache使用物理地址進(jìn)行尋址,因此稱為物理Cache。使用TLB和物理cache一起工作的過程如下圖:

圖片圖片

如果不使用虛擬存儲(chǔ)器,處理器送出的地址會(huì)直接訪問物理Cache,而現(xiàn)在要先經(jīng)過TLB才能再訪問物理Cache,因此必然會(huì)增加流水線的延遲,如果還想獲得和以前一樣的運(yùn)行頻率,就需要將訪問TLB的過程單獨(dú)使用一級(jí)流水線,但是這樣就增加了分支預(yù)測(cè)失敗時(shí)的懲罰(penalty),也增加了load指令的延遲,不是一個(gè)很好的做法。

為什么不使用Cache來直接緩存從虛擬地址到數(shù)據(jù)的關(guān)系呢?當(dāng)然是可以的,因?yàn)檫@個(gè)Cache使用虛擬地址來尋址,稱之為虛擬Cache。既然使用虛擬Cache,可以直接從虛擬地址得到對(duì)應(yīng)的數(shù)據(jù),那么是不是就不使用TLB了呢?當(dāng)然不是這樣,因?yàn)橐坏〤ache發(fā)生miss,仍然需要將對(duì)應(yīng)的虛擬地址轉(zhuǎn)換為物理地址,然后去物理內(nèi)存中獲得對(duì)應(yīng)的數(shù)據(jù),因此還需要TLB來加速從虛擬地址到物理地址的轉(zhuǎn)換過程。

如果使用虛擬地址,從虛擬Cache中找到了需要的數(shù)據(jù),就不需要再訪問TLB和物理內(nèi)存。在流水線中使用這種虛擬Cache,不會(huì)對(duì)處理器的時(shí)鐘產(chǎn)生明顯的負(fù)面影響,不過它會(huì)引起一些新的問題,需要耗費(fèi)額外的硬件進(jìn)行解決。

圖片圖片

MMU(Memory Management Unit):MMU是一種硬件或軟件模塊,負(fù)責(zé)處理虛擬地址到物理地址的轉(zhuǎn)換。它在操作系統(tǒng)的支持下,通過頁表或段表來實(shí)現(xiàn)地址映射。主要功能包括:

  • 地址轉(zhuǎn)換:將虛擬地址映射為對(duì)應(yīng)的物理地址。
  • 內(nèi)存保護(hù):根據(jù)權(quán)限位檢查訪問權(quán)限,防止非法訪問。
  • 內(nèi)存共享:實(shí)現(xiàn)多個(gè)進(jìn)程之間的內(nèi)存共享。
  • 頁面置換:當(dāng)頁面不在內(nèi)存中時(shí),觸發(fā)頁面置換機(jī)制將其加載到內(nèi)存中。

Cache:Cache是一種高速緩存,在CPU與主內(nèi)存之間起到緩沖作用。其目的是提高數(shù)據(jù)訪問速度和性能。主要功能包括:

  • 緩存命中:當(dāng)CPU請(qǐng)求讀取數(shù)據(jù)時(shí),先在Cache中查找是否存在該數(shù)據(jù),如果存在則直接返回給CPU,稱為命中;否則稱為缺失。
  • 緩存替換:當(dāng)Cache已滿且需要新的數(shù)據(jù)時(shí),會(huì)使用某種策略選擇一個(gè)被替換出去的緩存行。
  • 緩存寫策略:控制數(shù)據(jù)在何時(shí)寫回主內(nèi)存,可以是寫回(write-back)或直寫(write-through)策略。
  • 緩存一致性:確保多級(jí)緩存中的數(shù)據(jù)一致性,避免數(shù)據(jù)不一致問題。

Cache利用了局部性原理,即數(shù)據(jù)訪問往往具有時(shí)間和空間上的局部性。因此,通過將頻繁訪問的數(shù)據(jù)存儲(chǔ)在高速緩存中,可以大大減少對(duì)主內(nèi)存的訪問次數(shù),從而提高計(jì)算機(jī)系統(tǒng)的整體性能。

五、TLB 緩存的獨(dú)特之處

5.1與普通緩存的區(qū)別

在計(jì)算機(jī)的緩存體系中,TLB 緩存和普通數(shù)據(jù)緩存雖然都起著加速數(shù)據(jù)訪問的作用,但它們之間存在著顯著的區(qū)別 。

普通數(shù)據(jù)緩存,如 L1、L2 和 L3 緩存,主要用于緩存實(shí)際的數(shù)據(jù)。這些緩存存儲(chǔ)著 CPU 近期可能會(huì)訪問的數(shù)據(jù),當(dāng) CPU 需要訪問數(shù)據(jù)時(shí),首先會(huì)在這些普通數(shù)據(jù)緩存中查找。如果能夠在緩存中找到所需的數(shù)據(jù),就可以直接從緩存中讀取,避免了對(duì)速度較慢的內(nèi)存的訪問,從而大大提高了數(shù)據(jù)訪問的速度。例如,在一個(gè)簡(jiǎn)單的整數(shù)加法運(yùn)算中,CPU 需要讀取參與運(yùn)算的兩個(gè)整數(shù)。如果這兩個(gè)整數(shù)已經(jīng)被緩存在 L1 緩存中,CPU 就可以直接從 L1 緩存中獲取它們,而無需訪問內(nèi)存,這使得運(yùn)算能夠快速完成。

而 TLB 緩存則有著不同的使命,它主要緩存的是頁表數(shù)據(jù),其目的是加速虛擬地址到物理地址的轉(zhuǎn)換過程 。在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,由于采用了虛擬內(nèi)存機(jī)制,程序使用的是虛擬地址,而實(shí)際的數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中。為了訪問物理內(nèi)存中的數(shù)據(jù),需要將虛擬地址轉(zhuǎn)換為物理地址,這個(gè)轉(zhuǎn)換過程依賴于頁表。頁表存儲(chǔ)了虛擬地址與物理地址的映射關(guān)系,但由于頁表通常存儲(chǔ)在內(nèi)存中,訪問內(nèi)存中的頁表會(huì)帶來較大的延遲。

TLB 緩存作為頁表的高速緩存,存儲(chǔ)了近期最常訪問的頁表項(xiàng)。當(dāng) CPU 需要進(jìn)行地址轉(zhuǎn)換時(shí),會(huì)首先在 TLB 緩存中查找,如果能夠在 TLB 緩存中找到對(duì)應(yīng)的映射關(guān)系,就可以快速完成地址轉(zhuǎn)換,大大減少了地址轉(zhuǎn)換的時(shí)間。比如,當(dāng)一個(gè)程序需要訪問某個(gè)虛擬地址的數(shù)據(jù)時(shí),CPU 會(huì)先將該虛擬地址發(fā)送到 TLB 緩存中進(jìn)行查找。如果 TLB 緩存命中,CPU 就可以立即獲取到對(duì)應(yīng)的物理地址,并使用該物理地址去訪問內(nèi)存中的數(shù)據(jù);如果 TLB 緩存未命中,CPU 才會(huì)去訪問內(nèi)存中的頁表,進(jìn)行地址轉(zhuǎn)換,這個(gè)過程會(huì)花費(fèi)更多的時(shí)間。

從緩存的數(shù)據(jù)類型和作用來看,普通數(shù)據(jù)緩存關(guān)注的是數(shù)據(jù)本身的快速訪問,而 TLB 緩存關(guān)注的是地址轉(zhuǎn)換的加速,它們?cè)谟?jì)算機(jī)系統(tǒng)中扮演著不同但又相互配合的角色,共同為提高計(jì)算機(jī)系統(tǒng)的性能而努力 。

5.2特殊的虛擬地址映射

TLB 緩存中的虛擬地址和物理地址映射關(guān)系具有一些獨(dú)特的特點(diǎn)。

首先,內(nèi)存映射的最小單位是頁,通常一頁的大小為 4KB 。這就意味著 TLB 在存儲(chǔ)虛擬地址和物理地址的映射關(guān)系時(shí),是以頁為單位進(jìn)行的。由于頁的大小是固定的,所以 TLB 實(shí)際上不需要存儲(chǔ)虛擬地址和物理地址的低 12 位。因?yàn)閷?duì)于同一頁內(nèi)的不同地址,其低 12 位表示的是頁內(nèi)偏移,在虛擬地址和物理地址中是相同的,所以沒有必要存儲(chǔ)這部分信息。

例如,對(duì)于一個(gè)虛擬地址 0x12345678,其中低 12 位 0x678 表示的是頁內(nèi)偏移,在對(duì)應(yīng)的物理地址中,這部分偏移也是相同的,TLB 只需要存儲(chǔ)虛擬地址的高 32 位(假設(shè)是 32 位系統(tǒng))中與頁表相關(guān)的部分,以及對(duì)應(yīng)的物理地址的高 32 位中與頁框相關(guān)的部分,就可以完整地表示這個(gè)虛擬地址到物理地址的映射關(guān)系 。

其次,當(dāng) TLB 命中時(shí),會(huì)一次性從緩存中拿出整個(gè)物理地址,這與數(shù)據(jù)緩存操作的最小單位不同 。在數(shù)據(jù)緩存中,通常是以緩存行(cache line)為單位進(jìn)行數(shù)據(jù)的讀取和寫入,緩存行的大小一般比一頁要小得多。而 TLB 操作的最小單位是一個(gè)物理地址,這是因?yàn)?TLB 的主要作用是提供地址轉(zhuǎn)換服務(wù),一旦命中,就需要提供完整的物理地址,以便 CPU 能夠準(zhǔn)確地訪問內(nèi)存中的數(shù)據(jù)。

另外,TLB 中虛擬地址是否需要 index 域,取決于 cache 的組織形式 。如果是全相連高速緩存,那么 TLB 中不需要 index 域。在全相連高速緩存中,任何一個(gè)虛擬地址都可以映射到 TLB 中的任何一個(gè)表項(xiàng),查找時(shí)需要將虛擬地址與 TLB 中的所有表項(xiàng)進(jìn)行比較,所以不需要 index 域來確定查找的位置。而如果使用多路組相連高速緩存,TLB 中依然需要 index 域。

例如,在一個(gè) 4 路組相連的 TLB 中,虛擬地址的一部分會(huì)被用來計(jì)算 index 值,通過這個(gè) index 值可以確定該虛擬地址對(duì)應(yīng)的 TLB 表項(xiàng)組,然后在組內(nèi)的 4 個(gè)表項(xiàng)中進(jìn)行查找,這樣可以在一定程度上提高查找的效率,同時(shí)也減少了沖突的發(fā)生。

六、實(shí)際應(yīng)用與優(yōu)化策略

6.1在操作系統(tǒng)中的角色

在操作系統(tǒng)中,TLB 扮演著至關(guān)重要的角色,是內(nèi)存管理的關(guān)鍵環(huán)節(jié) 。

進(jìn)程切換是操作系統(tǒng)中常見的操作,當(dāng)從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程時(shí),地址空間也會(huì)發(fā)生變化。由于不同進(jìn)程擁有獨(dú)立的虛擬地址空間,相同的虛擬地址在不同進(jìn)程中可能會(huì)映射到不同的物理地址。例如,進(jìn)程 A 中虛擬地址 0x1000 可能映射到物理地址 0x20000,而在進(jìn)程 B 中,虛擬地址 0x1000 卻映射到物理地址 0x30000 。如果在進(jìn)程切換時(shí)不進(jìn)行相應(yīng)處理,TLB 中緩存的前一個(gè)進(jìn)程的地址映射關(guān)系就會(huì)影響新進(jìn)程的地址轉(zhuǎn)換,導(dǎo)致錯(cuò)誤的內(nèi)存訪問。

為了解決這個(gè)問題,早期的做法是在進(jìn)程切換時(shí)直接清空整個(gè) TLB。這樣雖然保證了新進(jìn)程不會(huì)使用到舊進(jìn)程錯(cuò)誤的地址映射,但也帶來了性能問題。因?yàn)榍蹇?TLB 后,新進(jìn)程開始執(zhí)行時(shí),TLB 中沒有任何有效的映射關(guān)系,會(huì)導(dǎo)致大量的 TLB 缺失,CPU 需要頻繁地訪問內(nèi)存中的頁表來進(jìn)行地址轉(zhuǎn)換,這大大增加了內(nèi)存訪問的延遲,降低了程序的運(yùn)行效率 。

后來,ASID(地址空間標(biāo)識(shí)符)的引入有效地減少了進(jìn)程切換時(shí)清空 TLB 的需求 。每個(gè)進(jìn)程都被分配一個(gè)唯一的 ASID,TLB 中的每個(gè)表項(xiàng)除了包含虛擬地址和物理地址的映射關(guān)系外,還包含所屬進(jìn)程的 ASID。當(dāng)進(jìn)行進(jìn)程切換時(shí),如果新進(jìn)程的 ASID 與舊進(jìn)程不同,TLB 會(huì)識(shí)別出這是不同進(jìn)程的地址映射,不會(huì)使用舊進(jìn)程的映射關(guān)系,從而避免了地址混淆。而如果新進(jìn)程的 ASID 與之前某個(gè)進(jìn)程相同,并且之前該 ASID 對(duì)應(yīng)的 TLB 條目未被覆蓋或刷新,那么這些映射仍然有效,可以直接使用,無需重新加載頁表項(xiàng),這就大大提高了進(jìn)程切換時(shí)的效率,減少了因 TLB 清空和重新加載帶來的性能損耗 。

6.2優(yōu)化內(nèi)存訪問效率的方法

(1)代碼編寫技巧

在代碼編寫過程中,有一些技巧可以提高 TLB 命中率,進(jìn)而優(yōu)化內(nèi)存訪問效率 。

連續(xù)訪問內(nèi)存:充分利用程序訪問的局部性原理,盡量保證對(duì)內(nèi)存的訪問是連續(xù)的。例如,在遍歷數(shù)組時(shí),按照數(shù)組元素在內(nèi)存中的存儲(chǔ)順序依次訪問。假設(shè)有一個(gè)整型數(shù)組int array[100];,如果順序訪問for (int i = 0; i < 100; i++) { int value = array[i]; },這樣內(nèi)存訪問具有良好的空間局部性,當(dāng)訪問一個(gè)內(nèi)存頁中的元素時(shí),該頁中的其他元素很可能也會(huì)被訪問到,從而提高了 TLB 的命中率。相反,如果隨機(jī)訪問數(shù)組元素,如for (int i = 0; i < 100; i++) { int index = rand() % 100; int value = array[index]; },會(huì)導(dǎo)致頻繁的 TLB 缺失,因?yàn)槊看卧L問的內(nèi)存頁可能都不同,TLB 很難緩存到有效的映射關(guān)系。

合理安排數(shù)據(jù)結(jié)構(gòu):根據(jù)數(shù)據(jù)的訪問模式來設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)。對(duì)于經(jīng)常一起訪問的數(shù)據(jù),盡量將它們放在相鄰的內(nèi)存位置。比如,在設(shè)計(jì)一個(gè)游戲角色的數(shù)據(jù)結(jié)構(gòu)時(shí),如果角色的位置、生命值、攻擊力等屬性經(jīng)常被同時(shí)訪問,就可以將這些屬性緊密排列在結(jié)構(gòu)體中。struct GameCharacter { int positionX; int positionY; int health; int attackPower; };,這樣在訪問角色的某個(gè)屬性時(shí),其他相關(guān)屬性很可能也在同一個(gè)內(nèi)存頁中,提高了 TLB 命中率。而如果將這些屬性分散在不同的結(jié)構(gòu)體或內(nèi)存位置,就會(huì)增加 TLB 缺失的概率 。

(2)硬件與軟件協(xié)同

硬件設(shè)計(jì)和操作系統(tǒng)管理對(duì) TLB 性能的協(xié)同優(yōu)化作用至關(guān)重要 。

在硬件方面,增加 TLB 的容量可以緩存更多的虛擬地址到物理地址的映射關(guān)系,從而提高命中率。例如,將 TLB 的條目數(shù)從 64 個(gè)增加到 128 個(gè),就能存儲(chǔ)更多近期使用過的頁表項(xiàng),減少訪問內(nèi)存中頁表的次數(shù) 。優(yōu)化 TLB 的結(jié)構(gòu),采用更先進(jìn)的緩存組織方式,如多級(jí) TLB 結(jié)構(gòu)或采用關(guān)聯(lián)性更強(qiáng)的緩存結(jié)構(gòu),也可提升查找效率和命中率。例如,使用組相聯(lián)緩存結(jié)構(gòu),相比直接映射緩存,能在同一組內(nèi)存儲(chǔ)多個(gè)頁表項(xiàng),降低因地址沖突導(dǎo)致的緩存未命中情況 。

操作系統(tǒng)層面也有很多優(yōu)化措施,合理選擇頁面大小可以減少頁表項(xiàng)的數(shù)量,從而提高頁表緩存的命中率。較大的頁面可以減少頁表的大小,使更多的頁表項(xiàng)能夠放入緩存中,但可能會(huì)導(dǎo)致內(nèi)存碎片增加;較小的頁面則可以更精細(xì)地分配內(nèi)存,但會(huì)增加頁表的大小。操作系統(tǒng)需要根據(jù)具體的硬件環(huán)境和應(yīng)用場(chǎng)景來選擇合適的頁面大小 。

采用高效的內(nèi)存分配算法,使進(jìn)程的內(nèi)存分配更具局部性,讓相關(guān)的頁表項(xiàng)更有可能被連續(xù)訪問,從而提高頁表緩存命中率。像伙伴系統(tǒng)算法、slab分配器等,能根據(jù)進(jìn)程的需求合理分配內(nèi)存,減少內(nèi)存碎片,提高內(nèi)存訪問的局部性 。

只有硬件和軟件相互配合,共同優(yōu)化,才能充分發(fā)揮 TLB 的作用,最大程度地提高內(nèi)存訪問效率,提升計(jì)算機(jī)系統(tǒng)的整體性能 。

責(zé)任編輯:武曉燕 來源: 深度Linux
相關(guān)推薦

2013-10-16 09:28:14

亞馬遜AWSSDN

2013-10-16 09:33:36

亞馬遜AWSSDN

2011-08-11 17:05:26

2014-01-07 10:46:39

2024-07-11 08:34:48

2023-09-25 15:29:44

Go并發(fā)Goroutines

2022-02-11 10:47:17

CIOIT團(tuán)隊(duì)企業(yè)

2023-05-08 14:54:00

AI任務(wù)HuggingGPT

2019-11-27 10:40:34

數(shù)據(jù)工具CIO

2019-11-27 10:38:37

數(shù)據(jù)分析數(shù)據(jù)準(zhǔn)備工具

2009-07-28 10:36:58

云計(jì)算Google秘密武器

2025-05-14 00:01:10

RxJS異步編程響應(yīng)式

2011-06-02 10:24:11

iTravel蘋果

2023-02-24 10:26:34

語音AI人工智能

2025-06-12 08:00:00

Pythondataclass代碼

2025-05-27 10:00:00

Python數(shù)據(jù)類代碼

2015-03-30 16:58:05

秘密武器華為

2015-06-08 09:50:07

Android M谷歌

2025-01-06 23:33:04

2019-02-27 09:44:01

CIO秘密武器顧問
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)