天天看點

一個故事看懂CPU的TLB

Hi,我是CPU一号工廠中的房間的阿Q,還記得我嗎,真是好久不見了~

我所在的CPU是一個八核CPU,就有八個工作工廠中的房間,那運作起來速度杠杆的~

一大早,我們一号工廠中的房間MMU(記憶體管理單元)部門的小黑就來到上司辦公室,恰好我也在。

“上司,聽說您同意了阿Q他們的方案,給每個工廠中的房間都劃撥了緩存建設預算?”

“你這小子,消息還挺靈通的。沒錯,記憶體那家夥實在太慢了,加了緩存後,不用每次都從記憶體讀取資料,能讓咱們的性能提升不少”,上司說到。

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

上司眉頭一緊,問道:“你們要申請經費幹什麼?”

“我們也要建設緩存”

“你們MMU部門做位址翻譯工作,要緩存做什麼,怕不是看上司給我們撥了款,眼紅了吧?”,我在一旁說到。

小黑轉過身來,看着我說道:“說我眼紅,我倒是問你,你知道虛拟位址翻譯的過程嗎?”

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

“嘿,你小子不錯啊,記性挺好”,小黑有點不敢相信,随後又問到:“既然你知道,那我再問你,這讀取一次資料,需要通路幾次記憶體?”

我思考了一下,開始算了起來。從頁目錄表中讀取一次,從頁表中再讀取一次,最後通路頁面内資料再讀取一次,總共就是三次。

“需要通路三次記憶體!”,我回答到。

小黑點了點頭說道:“沒錯,你知道的,記憶體那家夥本來就慢,這每讀寫一個資料,都要通路記憶體三次,這誰頂得住啊?”

說的是啊,記憶體那家夥慢我是知道的,但讀寫一次就要折騰三回,我倒是沒想過。

“就這還是32位位址的情況,我還沒算64位下變成了4級頁表呢,那通路記憶體的次數就更多了!”

“好在咱們馬上就要建設緩存設施了,也不用每次都從記憶體讀取資料,要是緩存能找到,就不用讀取記憶體了嘛!”

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

“要是能把位址翻譯的結果也緩存起來就好,就不用每次都從記憶體查了”,我陷入了思考。

“你看,你跟我想到一會兒去了,是以我才向上司申請,咱們MMU部門也加上緩存,這樣位址翻譯變快了,咱們整個工廠中的房間工作效率才高嘛!”

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

“沒問題!”,上司這麼一說,小黑高興壞了。

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

“我還沒想的很成熟,隻有個大概的方案”

“快給我透露一下”

“好吧,告訴你也無妨!我舉個例子吧,假設要翻譯的虛拟位址是<code>0x12345678</code>,這是一個32位的位址,前面的20位是<code>0x12345000</code>,經過兩次查表後,定位到真實的實體頁面<code>0x00abc000</code>,最後再加上頁内偏移,翻譯結果就是<code>0x00abc678</code>”

“位址翻譯完成後,将虛拟頁編号<code>0x12345</code>和實體頁編号<code>0x00abc</code>的映射關系記錄起來放到緩存中”

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

“聽上去很不錯,期待早點上馬啊!”

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

一進門,隻見小黑和其他幾個工廠中的房間的MMU部門負責人正在緊張的讨論着,一旁的畫闆上畫了不少條條框框的圖。

“小黑老哥,你們這是在做什麼呢?”

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

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

“就是虛拟位址翻譯的結果,我們不知道怎麼存了!”

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

二号工廠中的房間MMU負責人連連揮手,“沒你想的這麼簡單,按照你這種存法,那在翻譯位址的時候,怎麼查找?難道要全部掃描一遍?”

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

“那可不行,咱們CPU的目标就是要把性能優化到極緻,這種方案上了,上司還不得罵死我”,小黑說到。

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

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

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

“可不是嘛,是以我們才頭疼啊”

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

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

“什麼辦法?快說說看”

“分組連接配接!”

“分組連接配接?”,衆人問到。

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

“聽上去不錯唉,這樣既降低了沖突,周遊也隻需在分組區間裡進行了,工作量大大降低了,真是個好辦法”

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

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

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

“好,沒問題,咱們下來測試下”

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

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

“也不用全部清掉吧,像有些核心頁面,是所有程序共享的,就可以保留啊”

小黑點了點頭,“有道理,看來得給位址翻譯記錄增加一個标記,用來标記是不是全局有效”

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

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

【完】

主機闆上這家夥,要當CPU和記憶體的中間商!

主機闆上來了一個新鄰居,CPU慌了!

CPU明明8個核,網卡為啥拼命折騰一号核?

上一篇: jenkins
下一篇: memcache