Hugemem Kernel Explained

jolly10發表於2010-10-14

Feature: High Memory In The Linux Kernel

對 RedFlag DC Server 所帶的 Hugemem 核心的作用,做了一個詳細的解釋,轉貼這裡。
Hugemem Kernel Explained

紅旗DC系列Linux作業系統(x86平臺)中帶有四類核心:

* UP (支援單核心)
* SMP (支援多核心)
* hugemem
* Icc* (用intel C編譯器編譯的核心)

[@more@]

其中hugemem核心往往引起很多困惑,這裡希望能一勞永逸地把hugemem解釋清楚。


Hugemem vs. SMP

x86平臺下, 紅旗DC4.1和5.0所帶的smp和hugemem核心都開啟了PAE支援,也就是說都可以支援4G以上的實體記憶體。引入hugememe核心的目的_不是_支援超過4G實體記憶體(SMP核心就可以支援了),而是更穩定地支援大記憶體x86系統(所謂大記憶體可以簡單理解為超過12G記憶體的系統)。


smp和hugemem核心的 _唯一_區別是hugemem核心中打入了4G/4G補丁,使用4G/4G補丁可以將直接對映的核心資料程式碼地址空間從1G擴大到4G,將程式的虛擬地址空間也由 3G擴大到4G。當實體記憶體過多時,管理這些實體記憶體的工作本身會佔用不少寶貴的核心地址空間(所謂低端記憶體),此時雖然總的實體記憶體還有不少空閒,由於低端記憶體耗盡,也可能會導致記憶體緊張,觸發OOM (Out of memory) killer,導致應用終止甚至核心崩潰。


如果超過12G實體記憶體,一般建議使用hugemem核心。不過,hugemem會帶來一定的效能損失。


以上說明對於一般使用者應該足夠了,如果想了解4G/4G補丁的更多細節,請繼續往下看...

大記憶體x86系統帶來的問題


4G/4G補丁主要應用於大記憶體x86系統(所謂大記憶體可以簡單理解為超過12G記憶體的系統),這樣的系統往往需要更多的核心地址空間和使用者地址空間。

在x86架構下,我們知道虛擬地址空間的大小為4G。在這4G空間中,使用者空間佔3G (0x00000000到0xbfffffff),核心空間佔1G(0xc0000000到0xffffffff)。這樣的分配策略成為3G/1G分配。這種分配方式對於擁有1G實體記憶體以下的系統是沒有任何問題的,即使超過1G實體記憶體,3G/1G分配策略也沒有什麼問題,因為核心可以在高階記憶體區域 (實體地址1G以上的記憶體)中存放一些核心資料結構(比如頁緩衝等)。然而,隨著實體記憶體的增多,3G/1G分配策略的問題也逐漸會暴露出來。這是因為一些關鍵的核心資料結構(比如用於管理實體記憶體的mem_map[])是存放在1G核心空間之內的。對於32G記憶體的系統,mem_map[]會佔用近 0.5G的低端記憶體(實體地址896M以下的記憶體),這樣留給核心其他部分的記憶體就不到所有記憶體的1.5%;而對於64G記憶體的系統,mem_map[] 本身就會耗盡所有的低端記憶體,造成系統無法啟動。把mem_map[]放到高階記憶體的做法也不太實際,因為mem_map[]和記憶體管理,體系結構相關底層實現,檔案系統以及驅動等幾乎所有的核心的關鍵部分均有聯絡。

4G/4G的作用

與3G/1G不同,4G/4G分配方式可以使核心空間由1G增加到4G,而使用者空間也由3G增加到4G。從 /proc/PID/maps 檔案中可以直觀地看到4G/4G所起的作用:


00e80000-00faf000 r-xp 00000000 03:01 175909 /lib/tls/libc-2.3.2.so

00faf000-00fb2000 rw-p 0012f000 03:01 175909 /lib/tls/libc-2.3.2.so

[...]

feffe000-ff000000 rwxp fffff000 00:00 0


從上面的maps可以看出,堆疊的棧底地址為0xff000000 (4GB 減去 16MB)。

從/proc/maps中則可以看到核心擁有了4G大小的低端記憶體,即使對於64G實體記憶體的系統,也有3.1G低端記憶體可供使用:


MemTotal: 66052020 kB

MemFree: 65958260 kB

HighTotal: 62914556 kB

HighFree: 62853140 kB

LowTotal: 3137464 kB

LowFree: 3105120 kB


相比3G/1G分配策略,對於4G實體記憶體系統,使用4G/4G分配可以增加低端記憶體達3倍以上,而對於32G實體記憶體系統,則會有更多的提升,達到原來的6倍。 理論上,4G/4G策略可以支援實體記憶體達200G的x86系統(如果硬體沒有限制的話),即使對於這樣的系統,4G/4G策略也能保證留有1G可用的低端記憶體。

4G/4G的代價

天下沒有免費的午餐,4G/4G也是如此。4G/4G透過完全分離使用者空間和核心空間的地址對映來增加低端記憶體,這樣做會帶來一些效能損失,具體而言,當發生上下文切換的時候(比如程式呼叫系統呼叫或者發生中斷),必須重新裝載頁表(3G/1G策略下不需要載入,因為核心可以直接“借用”每個程式的頁表進行記憶體對映),頁表的重新裝載後必須清空TLB(否則的話TLB中記錄的對映就和新的頁表不一致了),而清空TLB是一個很費時的操作,原先快取於 TLB中的“舊”的對映會被丟掉,這一損失到還在其次(因為不經TLB直接從CPU快取中讀取頁表也並不會有太大延遲),最大的損失在於清空TLB(透過操作%cr3)這個操作本身代價很高。

何時使用(or不使用)4G/4G?

對於這個問題,沒有放之四海而皆準的答案。只有一些拇指定律。一般情況下,超過16G記憶體幾乎肯定需要使用4G/4G (除非執行的應用負載很輕,不過大記憶體系統很少有負載輕的情況),如果負載很重(不如執行資料庫進行著大量I/O操作),那麼12G以上的系統就應考慮使用4G/4G。也可以透過觀察空閒低端記憶體大小來大體判斷一下(/proc/meminfo),如果空閒低端記憶體(LowFree)小於100M,那麼就可以考慮使用4G/4G了。8G以下的系統一般不必使用4G/4G。


需要指出的是,如果需要大記憶體,最好的解決方法是用64位系統,而不是使用4G/4G。

原文地址

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/271283/viewspace-1039721/,如需轉載,請註明出處,否則將追究法律責任。

相關文章