<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 默認頁大小是 4KB

          共 2798字,需瀏覽 6分鐘

           ·

          2020-08-13 22:28

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

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

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

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

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

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

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

          頁表項

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

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

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

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

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

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

          碎片化

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

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

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

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

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

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

          總結(jié)

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

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

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

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


          原創(chuàng)小號來襲,帥地申請了個小號,我會在這個公眾號分享讀者問過我的問題,并且給予最真實的回答,同時也會分享自己學(xué)習(xí)方法、掙錢經(jīng)歷、工作經(jīng)歷、個人經(jīng)歷、沙雕日常,我相信,我的經(jīng)歷與想法,一定可以給你帶來一些幫助!目前是一周1~2更,掃一掃進入帥地的原創(chuàng)私密沙雕小號

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产成人久久777777黄蓉 | 成人69视频 | 久久国产精品久久 | 色欲影视,淫色淫香 | 欧美舔逼视频 |