自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

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

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

一、TLB緩存是什么?

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

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

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

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

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

圖片圖片

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

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

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

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

二、地址轉(zhuǎn)換

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

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

2.1 單級頁表

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

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

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

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

圖片圖片

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

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

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

2.2 多級頁表

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

圖片圖片

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

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

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

圖片圖片

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

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

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

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

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

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

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

三、TLB工作原理

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

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

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

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

圖片圖片

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

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

3.2TLB原理

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

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

⑴TLB的特殊

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

圖片圖片

⑵TLB的別名問題

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

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

⑶TLB的歧義問題

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

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

⑷TLB表項

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

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

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

⑸全相連 - full associative

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

⑹直接匹配

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

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

⑺組相連 - set-associative

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

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

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

⑻LB表項更新

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

1. TLB miss發(fā)生后,CPU從RAM獲取頁表項,會自動更新TLB表項

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

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

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

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

3.3映射方式剖析

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

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

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

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

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

四、TLB緩存機制

4.1MMU

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

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

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

(1)VA和PA

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

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

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

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

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

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

MMU將VA映射到PA是以頁(page)為單位的,對于32位的CPU,通常一頁為4k,物理內(nèi)存中的一個物理頁面稱頁為一個頁框(page frame)。虛擬地址空間劃分成稱為頁(page)的單位,而相應(yīng)的物理地址空間也被進行劃分,單位是頁框(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)中取出保存在其中的第一級頁表(translation table)的基地址,這個基地址指的是PA,也就是說頁表是直接按照這個地址保存在物理內(nèi)存中的。
  • ⑵以TTB中的內(nèi)容為基地址,以VA[31:20]為索引值在一級頁表中查找出一項(2^12=4096項),這個頁表項(也稱為一個描述符,descriptor)保存著第二級頁表(coarse page table)的基地址,這同樣是物理地址,也就是說第二級頁表也是直接按這個地址存儲在物理內(nèi)存中的。
  • ⑶以VA[19:12]為索引值在第二級頁表中查出一項(2^8=256),這個表項中就保存著物理頁面的基地址,我們知道虛擬內(nèi)存管理是以頁為單位的,一個虛擬內(nèi)存的頁映射到一個物理內(nèi)存的頁框,從這里就可以得到印證,因為查表是以頁為單位來查的。
  • ⑷有了物理頁面的基地址之后,加上VA[11:0]這個偏移量(2^12=4KB)就可以取出相應(yīng)地址上的數(shù)據(jù)了。

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

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

CPU訪問內(nèi)存時的硬件操作順序,各步驟在圖中有對應(yīng)的標號:

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

2.頁表項中不僅保存著物理頁面的基地址,還保存著權(quán)限和是否允許cache的標志。MMU首先檢查權(quán)限位,如果沒有訪問權(quán)限,就引發(fā)一個異常給CPU內(nèi)核。然后檢查是否允許cache,如果允許cache就啟動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中,同時返回給CPU內(nèi)核。但是cache并不是只去CPU內(nèi)核所需要的數(shù)據(jù),而是把相鄰的數(shù)據(jù)都去上來緩存,這稱為一個cache line。ARM920T的cache line是32個字節(jié),例如CPU內(nèi)核要讀取地址0x30000134~0x3000137的4個字節(jié)數(shù)據(jù),cache會把地址0x30000120~0x3000137(對齊到32字節(jié)地址邊界)的32字節(jié)都取上來緩存。

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

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

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

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

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

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

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

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

具體步驟如下:

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

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

4.2 Cache的設(shè)計

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

圖片圖片

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

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

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

圖片圖片

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

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

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

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

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

五、TLB 緩存的獨特之處

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

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

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

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

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

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

5.2特殊的虛擬地址映射

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

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

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

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

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

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

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

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

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

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

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

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

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

(1)代碼編寫技巧

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

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

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

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

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

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

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

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

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

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

2013-10-16 09:28:14

亞馬遜AWSSDN

2013-10-16 09:33:36

亞馬遜AWSSDN

2014-01-07 10:46:39

2011-08-11 17:05:26

2023-09-25 15:29:44

Go并發(fā)Goroutines

2024-07-11 08:34:48

2022-02-11 10:47:17

CIOIT團隊企業(yè)

2023-05-08 14:54:00

AI任務(wù)HuggingGPT

2019-11-27 10:40:34

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

2009-07-28 10:36:58

云計算Google秘密武器

2019-11-27 10:38:37

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

2011-06-02 10:24:11

iTravel蘋果

2023-02-24 10:26:34

語音AI人工智能

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秘密武器顧問

2020-04-29 09:24:48

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

2017-09-25 18:33:00

美國硅谷互聯(lián)網(wǎng)

2024-08-19 09:22:48

點贊
收藏

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