一個故事看懂CPU的TLB

  • 2021 年 9 月 28 日
  • 筆記

Hi,我是CPU一號車間的阿Q,還記得我嗎,真是好久不見了~

我所在的CPU是一個八核CPU,就有八個工作車間,那運行起來速度槓桿的~

虛擬地址翻譯

一大早,我們一號車間MMU(內存管理單元)部門的小黑就來到領導辦公室,恰好我也在。

  

「領導,聽說您同意了阿Q他們的方案,給每個車間都劃撥了緩存建設預算?」

「你這小子,消息還挺靈通的。沒錯,內存那傢伙實在太慢了,加了緩存後,不用每次都從內存讀取數據,能讓咱們的性能提升不少」,領導說到。

「那我們MMU部門也要申請一筆經費」,小黑說到。

領導眉頭一緊,問道:「你們要申請經費幹什麼?」

「我們也要建設緩存」

「你們MMU部門做地址翻譯工作,要緩存做什麼,怕不是看領導給我們撥了款,眼紅了吧?」,我在一旁說到。

小黑轉過身來,看着我說道:「說我眼紅,我倒是問你,你知道虛擬地址翻譯的過程嗎?」

這可難不倒我,以前就沒少聽他說過,「怎麼不知道?以32位的虛擬地址為例,一個32位的虛擬地址分為三部分,分別是頁目錄索引、頁表索引、頁內偏移。翻譯的時候,從CR3寄存器中取出頁目錄地址,根據頁目錄索引找到頁表,再根據頁表索引找到物理內存頁面,最後根據頁內偏移,完成尋址。我說的對吧?」

 

 

 

「嘿,你小子不錯啊,記性挺好」,小黑有點不敢相信,隨後又問到:「既然你知道,那我再問你,這讀取一次數據,需要訪問幾次內存?」

我思考了一下,開始算了起來。從頁目錄表中讀取一次,從頁表中再讀取一次,最後訪問頁面內數據再讀取一次,總共就是三次。

「需要訪問三次內存!」,我回答到。

小黑點了點頭說道:「沒錯,你知道的,內存那傢伙本來就慢,這每讀寫一個數據,都要訪問內存三次,這誰頂得住啊?」

說的是啊,內存那傢伙慢我是知道的,但讀寫一次就要折騰三回,我倒是沒想過。

「就這還是32位地址的情況,我還沒算64位下變成了4級頁表呢,那訪問內存的次數就更多了!」

「好在咱們馬上就要建設緩存設施了,也不用每次都從內存讀取數據,要是緩存能找到,就不用讀取內存了嘛!」

「可是查頁目錄和頁表還是得要兩次啊」,小黑說到。

「要是能把地址翻譯的結果也緩存起來就好,就不用每次都從內存查了」,我陷入了思考。

「你看,你跟我想到一會兒去了,所以我才向領導申請,咱們MMU部門也加上緩存,這樣地址翻譯變快了,咱們整個車間工作效率才高嘛!」

  

這時,領導站了起來,說道:「唉~格局要打開,光你們一號車間提高不行,得發動全廠八個車間一起。小黑,經費的問題不用擔心,這事由你牽頭,把其他幾個車間的MMU部門負責人召集起來開個會,把你說的方案落地下去」

「沒問題!」,領導這麼一說,小黑高興壞了。

地址翻譯緩存

回去的路上,我又忍不住好奇,向小黑打聽起來:「你們這翻譯地址用的緩存,準備怎麼個弄法?」

「我還沒想的很成熟,只有個大概的方案」

「快給我透露一下」

「好吧,告訴你也無妨!我舉個例子吧,假設要翻譯的虛擬地址是0x12345678,這是一個32位的地址,前面的20位是0x12345000,經過兩次查表後,定位到真實的物理頁面0x00abc000,最後再加上頁內偏移,翻譯結果就是0x00abc678

 

 

 

「地址翻譯完成後,將虛擬頁編號0x12345和物理頁編號0x00abc的映射關係記錄起來放到緩存中」

 

「在進行地址翻譯的時候,先去這個緩存里瞅一瞅,看看有沒有記錄過,如果有就直接用之前記錄的,找不到再去內存頁表中找。跟局部性原理類似,翻譯過的地址,在接下來一段時間內再次用到的可能性很大,所以這個緩存是很有必要的!」,小黑非常自信的說到。

 

 

 

「聽上去很不錯,期待早點上馬啊!」

TLB

過了幾天,我打算去MMU部門轉轉,想看看他們的緩存搞的咋樣了。

一進門,只見小黑和其他幾個車間的MMU部門負責人正在緊張的討論着,一旁的畫板上畫了不少條條框框的圖。

 

 

「小黑老哥,你們這是在做什麼呢?」

「我們正在研究這個翻譯記錄緩存項的存儲方式呢!你來的正好,我們討論了半天也沒什麼好的思路,快來幫我出出主意」

我有些好奇,問道:「什麼問題把你們都難倒了?」

「就是虛擬地址翻譯的結果,我們不知道怎麼存了!」

「這有什麼好糾結的,緩存空間就那麼大,一個翻譯結果就是一條記錄,一條一條的存唄」

二號車間MMU負責人連連揮手,「沒你想的這麼簡單,按照你這種存法,那在翻譯地址的時候,怎麼查找?難道要全部掃描一遍?」

我愣了一下,「啊這,我倒是沒想這麼多···不過緩存空間也不大,存不了太多翻譯結果,全部掃描也還好吧?」

「那可不行,咱們CPU的目標就是要把性能優化到極致,這種方案上了,領導還不得罵死我」,小黑說到。

我想了想,「有了,給虛擬頁編號取模,每個虛擬頁的翻譯記錄只能存在緩存中固定的位置,這樣不用全部掃描,一次就能定位,是不是很贊?」

小黑搖了搖頭:「這個方案我們剛才也討論過了,緩存空間有限,會導致大量的虛擬頁取模後映射到同一個存儲位置,就會經常衝突,也不是個好辦法!」

「看來還真有點麻煩啊」,我也不自覺的皺起了眉頭,陷入了思考之中。

「可不是嘛,所以我們才頭疼啊」

空氣突然安靜,所有人都在低頭沉思。

「哎,有了!」,一個念頭在我腦中閃現。

「什麼辦法?快說說看」

「分組連接!」

「分組連接?」,眾人問到。

「沒錯!把前面這兩種方案結合一下。可以把緩存存儲空間劃分很多個組,全部遍歷太慢,直接取模映射又容易衝突,那如果映射的結果不是一個固定的位置,而是一個分組呢?」

 

「聽上去不錯唉,這樣既降低了衝突,遍歷也只需在分組區間里進行了,工作量大大降低了,真是個好辦法」

小黑和大家都一致同意了我的想法。

「那怎麼分組呢,多少項為一組呢?」,有人問到。

「嗯,這個我也說不好,得做實驗驗證,2、4、8、16都可以試試,實踐出真知嘛!」

「好,沒問題,咱們下來測試下」

「我還有一個問題,你們的這個緩存項什麼時候更新呢?咱們在保護模式下,不同的進程中,同一個虛擬頁翻譯後對應的物理頁面可是不同的,你們可不要用了錯誤的緩存,那可就出大亂子了!」

「嗨,這還用你說,在場的各位干這份工作時間都不短了,這一點我們比你更清楚。進程切換的時候,會把新進程的頁目錄表基地址寫到CR3寄存器中,那時候我們就會把緩存中的數據全部清掉啦!」,小黑胸有成竹的說到。

「也不用全部清掉吧,像有些內核頁面,是所有進程共享的,就可以保留啊」

小黑點了點頭,「有道理,看來得給地址翻譯記錄增加一個標記,用來標記是不是全局有效」

 

一個月後,八個車間MMU部門的緩存全部建設完成,當天便投入使用,咱們這個CPU的運行效率一下突飛猛進,這緩存的威力可真是太大了。

為了跟我們的一二級緩存相區分,小黑還給他們的地址翻譯緩存取了一個響亮的名字:TLB——翻譯後備緩衝區。

【完】

相關閱讀