<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么 Linux 默認(rèn)頁大小是 4KB

          共 2977字,需瀏覽 6分鐘

           ·

          2020-08-09 05:42

          為什么這么設(shè)計(jì)(Why’s THE Design)是一系列關(guān)于計(jì)算機(jī)領(lǐng)域中程序設(shè)計(jì)決策的文章,我們?cè)谶@個(gè)系列的每一篇文章中都會(huì)提出一個(gè)具體的問題并從不同的角度討論這種設(shè)計(jì)的優(yōu)缺點(diǎn)、對(duì)具體實(shí)現(xiàn)造成的影響。如果你有想要了解的問題,可以在文章下面留言。

          我們都知道 Linux 會(huì)以頁為單位管理內(nèi)存,無論是將磁盤中的數(shù)據(jù)加載到內(nèi)存中,還是將內(nèi)存中的數(shù)據(jù)寫回磁盤,操作系統(tǒng)都會(huì)以頁面為單位進(jìn)行操作,哪怕我們只向磁盤中寫入一個(gè)字節(jié)的數(shù)據(jù),我們也需要將整個(gè)頁面中的全部數(shù)據(jù)刷入磁盤中。

          Linux 同時(shí)支持正常大小的內(nèi)存頁和大內(nèi)存頁(Huge Page)[^1],絕大多數(shù)處理器上的內(nèi)存頁的默認(rèn)大小都是 4KB,雖然部分處理器會(huì)使用 8KB、16KB 或者 64KB 作為默認(rèn)的頁面大小,但是 4KB 的頁面仍然是操作系統(tǒng)默認(rèn)內(nèi)存頁配置的主流;除了正常的內(nèi)存頁大小之外,不同的處理器上也包含不同大小的大頁面,我們?cè)?x86 處理器上就可以使用 2MB 的內(nèi)存頁。

          4KB 的內(nèi)存頁其實(shí)是一個(gè)歷史遺留問題,在上個(gè)世紀(jì) 80 年代確定的 4KB 一直保留到了今天。雖然今天的硬件比過去豐富了很多,但是我們?nèi)匀谎赜昧诉^去主流的內(nèi)存頁大小。如下圖所示,裝過機(jī)的人應(yīng)該對(duì)這里的內(nèi)存條非常熟悉:

          圖 1 - 隨機(jī)存取內(nèi)存

          在今天,4KB 的內(nèi)存頁大小可能不是最佳的選擇,8KB 或者 16KB 說不定是更好的選擇,但是這是過去在特定場(chǎng)景下做出的權(quán)衡。我們?cè)谶@篇文章中不要過于糾結(jié)于 4KB 這個(gè)數(shù)字,應(yīng)該更重視決定這個(gè)結(jié)果的幾個(gè)因素,這樣當(dāng)我們?cè)谟龅筋愃茍?chǎng)景時(shí)才可以從這些方面考慮當(dāng)下最佳的選擇,我們?cè)谶@篇文章中會(huì)介紹以下兩個(gè)影響內(nèi)存頁大小的因素,它們分別是:

          • 過小的頁面大小會(huì)帶來較大的頁表項(xiàng)增加尋址時(shí) TLB(Translation lookaside buffer)的查找速度和額外開銷;
          • 過大的頁面大小會(huì)浪費(fèi)內(nèi)存空間,造成內(nèi)存碎片,降低內(nèi)存的利用率;

          上個(gè)世紀(jì)在設(shè)計(jì)內(nèi)存頁大小時(shí)充分考慮了上述的兩個(gè)因素,最終選擇了 4KB 的內(nèi)存頁作為操作系統(tǒng)最常見的頁大小,我們接下來將詳細(xì)介紹以上它們對(duì)操作系統(tǒng)性能的影響。

          頁表項(xiàng)

          我們?cè)?為什么 Linux 需要虛擬內(nèi)存 一文中曾經(jīng)介紹過 Linux 中的虛擬內(nèi)存,每個(gè)進(jìn)程能夠看到的都是獨(dú)立的虛擬內(nèi)存空間,虛擬內(nèi)存空間只是邏輯上的概念,進(jìn)程仍然需要訪問虛擬內(nèi)存對(duì)應(yīng)的物理內(nèi)存,從虛擬內(nèi)存到物理內(nèi)存的轉(zhuǎn)換就需要使用每個(gè)進(jìn)程持有頁表。

          為了存儲(chǔ) 64 位操作系統(tǒng)中 128 TiB 虛擬內(nèi)存的映射數(shù)據(jù),Linux 在 2.6.10 中引入了四層的頁表輔助虛擬地址的轉(zhuǎn)換[^2],在 4.11 中引入了五層的頁表結(jié)構(gòu)[^3],在未來還可能會(huì)引入更多層的頁表結(jié)構(gòu)以支持 64 位的虛擬地址。

          圖 2 - 四層頁表結(jié)構(gòu)

          在如上圖所示的四層頁表結(jié)構(gòu)中,操作系統(tǒng)會(huì)使用最低的 12 位作為頁面的偏移量,剩下的 36 位會(huì)分四組分別表示當(dāng)前層級(jí)在上一層中的索引,所有的虛擬地址都可以用上述的多層頁表查找到對(duì)應(yīng)的物理地址[^4]。

          因?yàn)椴僮飨到y(tǒng)的虛擬地址空間大小都是一定的,整片虛擬地址空間被均勻分成了 N 個(gè)大小相同的內(nèi)存頁,所以內(nèi)存頁的大小最終會(huì)決定每個(gè)進(jìn)程中頁表項(xiàng)的層級(jí)結(jié)構(gòu)和具體數(shù)量,虛擬頁的大小越小,單個(gè)進(jìn)程中的頁表項(xiàng)和虛擬頁也就越多。

          因?yàn)槟壳暗奶摂M頁大小為 4096 字節(jié),所以虛擬地址末尾的 12 位可以表示虛擬頁中的地址,如果虛擬頁的大小降到了 512 字節(jié),那么原本的四層頁表結(jié)構(gòu)或者五層頁表結(jié)構(gòu)會(huì)變成五層或者六層,這不僅會(huì)增加內(nèi)存訪問的額外開銷,還會(huì)增加每個(gè)進(jìn)程中頁表項(xiàng)占用的內(nèi)存大小。

          碎片化

          因?yàn)閮?nèi)存映射設(shè)備會(huì)在內(nèi)存頁的層面工作,所以操作系統(tǒng)認(rèn)為內(nèi)存分配的最小單元就是虛擬頁。哪怕用戶程序只是申請(qǐng)了 1 字節(jié)的內(nèi)存,操作系統(tǒng)也會(huì)為它申請(qǐng)一個(gè)虛擬頁,如下圖所示,如果內(nèi)存頁的大小為 24KB,那么申請(qǐng) 1 字節(jié)的內(nèi)存會(huì)浪費(fèi) ~99.9939% 的空間。

          圖 3 - 大內(nèi)存的碎片化

          隨著內(nèi)存頁大小的增加,內(nèi)存的碎片化情況會(huì)越來越嚴(yán)重,小的內(nèi)存頁會(huì)減少內(nèi)存空間中的內(nèi)存碎片,提高內(nèi)存的利用率。上個(gè)世紀(jì)的內(nèi)存資源還沒有像今天這么豐富,在大多數(shù)情況下,內(nèi)存都不是限制程序運(yùn)行的資源,多數(shù)的在線服務(wù)都需要更多的CPU,而不是更多的內(nèi)存。不過在上個(gè)世紀(jì)內(nèi)存其實(shí)也是稀缺資源,所以提高稀缺資源的利用率是我們不得不考慮的事情:

          圖 4 - 內(nèi)存的價(jià)格

          上個(gè)世紀(jì)八九十年代的內(nèi)存條只有 512KB 或者 2MB,價(jià)格也貴得離譜,但是幾 GB 的內(nèi)存在今天卻非常常見[^8],所以雖然內(nèi)存的利用率仍然十分重要,但是在內(nèi)存的價(jià)格大幅降低的今天,碎片化的內(nèi)存不再是需要解決的關(guān)鍵問題了。

          除了內(nèi)存的利用率之外,較大的內(nèi)存頁也會(huì)增加內(nèi)存拷貝時(shí)的額外開銷,因?yàn)?Linux 上的寫時(shí)拷貝機(jī)制,在多個(gè)進(jìn)程共享同一塊內(nèi)存時(shí),當(dāng)其中的一個(gè)進(jìn)程修改了共享的虛擬內(nèi)存會(huì)觸發(fā)內(nèi)存頁的拷貝,這時(shí)操作系統(tǒng)的內(nèi)存頁越小,寫時(shí)拷貝帶來的額外開銷也就越小。

          總結(jié)

          就像我們?cè)谏厦嫣岬降模?KB 的內(nèi)存頁是上個(gè)世紀(jì)決定的默認(rèn)設(shè)置,從今天的角度來看,這很可能已經(jīng)是錯(cuò)誤的選擇了,arm64、ia64 等架構(gòu)已經(jīng)可以支持 8KB、16KB 等大小的內(nèi)存頁,隨著內(nèi)存的價(jià)格變得越來越低、系統(tǒng)的內(nèi)存變得越來越大,更大的內(nèi)存可能是操作系統(tǒng)更好的選擇,我們重新回顧一下兩個(gè)決定內(nèi)存頁大小的要素:

          • 過小的頁面大小會(huì)帶來較大的頁表項(xiàng)增加尋址時(shí) TLB(Translation lookaside buffer)的查找速度和額外開銷,但是也會(huì)減少程序中的內(nèi)存碎片,提高內(nèi)存的利用率;
          • 過大的頁面大小會(huì)浪費(fèi)內(nèi)存空間,造成內(nèi)存碎片,降低內(nèi)存的利用率,但是可以較少進(jìn)程中的頁表項(xiàng)以及 TLB 的尋址時(shí)間;

          這種類似的場(chǎng)景在我們做系統(tǒng)設(shè)計(jì)時(shí)也比較常見,舉一個(gè)不是特別恰當(dāng)?shù)睦樱?dāng)我們想要在集群上部署服務(wù)時(shí),每個(gè)節(jié)點(diǎn)上的資源是有限的,單個(gè)服務(wù)占用的資源可能會(huì)影響集群的資源利用率或者系統(tǒng)的額外開銷。如果我們?cè)诩褐胁渴?32 個(gè)占用 1 CPU 的服務(wù),那么可以充分利用集群中的資源,但是如此多的實(shí)例數(shù)會(huì)帶來較大的額外開銷;如果我們?cè)诩褐胁渴?4 個(gè)占用 8 CPU 的服務(wù),那么這些服務(wù)的額外開銷雖然很小,但是可能會(huì)在節(jié)點(diǎn)中留下很多空隙。到最后,我們還是來看一些比較開放的相關(guān)問題,有興趣的讀者可以仔細(xì)思考一下下面的問題:

          • Linux 中的扇區(qū)、塊和頁都有什么區(qū)別和聯(lián)系?
          • Linux 中的塊大小是如何決定的?常見的大小有哪些?

          如果對(duì)文章中的內(nèi)容有疑問或者想要了解更多軟件工程上一些設(shè)計(jì)決策背后的原因,可以在博客下面留言,作者會(huì)及時(shí)回復(fù)本文相關(guān)的疑問并選擇其中合適的主題作為后續(xù)的內(nèi)容。




          推薦閱讀




          學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進(jìn)群」即可


          站長(zhǎng) polarisxu

          自己的原創(chuàng)文章

          不限于 Go 技術(shù)

          職場(chǎng)和創(chuàng)業(yè)經(jīng)驗(yàn)


          Go語言中文網(wǎng)

          每天為你

          分享 Go 知識(shí)

          Go愛好者值得關(guān)注



          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丝袜电影一区 | 亚洲午夜免费视频 | 欧美人与动Zozo禽交大全 | 国产精品婷婷久久久久 | 99热.con|