Linux中hugepage的使用方法
Linux中hugepage的使用方法
Linux中使用hugepage有兩種方法,分別是
- hugetlb
- transparent huge page (THP)
其中,hugetlb基於顯式分配並保留的大頁,而THP按需將記憶體轉換成大頁,無需提前保留,提供更加靈活、對系統其他部分影響更小的大頁使用方式。
Hugetlb使用方法
分配大頁
-
預設size大頁
echo N > /proc/sys/vm/nr_hugepages
將試圖分配N個大頁,頁面大小是預設的(一般是2MB)。如果原來保留的頁面個數大於N,那麼將會釋放多出來的頁面。如果連續記憶體不夠將保留頁面數上升到N,則盡最大努力分配。cat /proc/sys/vm/nr_hugepages
可以檢視保留頁面個數。 -
在指定的NUMA結點試圖分配N個指定頁面大小的hugepage,修改或讀取檔案:
/sys/devices/system/node/node<node_id>/hugepages/hugepages-<page_size>/nr_hugepages
-
NUMA結點無關的指定頁面大小的hugepage:
/sys/kernel/mm/hugepages/hugepages-1048576kB/
。如果直接寫該檔案來提升頁面個數,將重複依次在各個NUMA結點試圖分配一個頁面(node0, node1, node2, node3, ..., node0, node1, node2, node3, ...)直到滿足或不可進一步分配,例如:- 在每個node資源充足的情況下,將均勻分配頁面到各個node。
- 若只有一個node可以分配大頁,則大頁全部分配到該node上。
- 若所有node可分配大頁的記憶體總量之和仍不能滿足N,則每個node盡最大努力分配大頁。
使用大頁
這裡僅介紹mmap使用大頁的方法。
在mmap的flag中新增MAP_HUGETLB
和<MAP_HUGE>。其中,<MAP_HUGE>為((N & MAP_HUGE_MASK) << MAP_HUGE_SHIFT)
,MAP_HUGE_MASK == 0x3f == 0b111111
,MAP_HUGE_SHIFT == 26
N
為大頁size的log2(來源:When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.)
例項:
void *myMalloc1GbPage(size_t size) {
int flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB |
((30 & MAP_HUGE_MASK) << MAP_HUGE_SHIFT); // 2^30 == 1G
int protection = PROT_READ | PROT_WRITE;
return mmap(NULL, size, protection, flags, -1, 0);
}
void *myMalloc2MbPage(size_t size) {
int flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB |
((21 & MAP_HUGE_MASK) << MAP_HUGE_SHIFT); // 2^21 == 2M
int protection = PROT_READ | PROT_WRITE;
return mmap(NULL, size, protection, flags, -1, 0);
}
Transparent Huge Page
分配大頁
不需要顯式分配,只需要修改/sys/kernel/mm/transparent_hugepage/enabled
為madvise
或always
即可開啟THP。
使用大頁
為了使用大頁,可以使用posix_memalign(3)
分配aligned記憶體。若為madvise
模式,則需要在程式碼中使用madvise(ptr, size, MADV_HUGEPAGE)
來在指定區域開啟大頁。
例項:
void *myMalloc2MbTHP(size_t size) {
void *ptr;
int ret = posix_memalign(&ptr, 1 << 21, size);
if (ret != 0) {
// ERROR HANDLE
}
madvise(ptr, size, MADV_HUGEPAGE);
return ptr;
}
madvise
正如其名,僅提供“建議”,具體是否分配大頁還要根據實際情況。如果THP被設定為always
,那麼是否madvise(MADV_HUGEPAGE)
就不重要了。
hugetlb和THP的優劣
THP目前僅支援2MB的大頁,不支援1GB大頁,因此若想使用1GB大頁則只能使用hugetlb。(NV的技術人員已經實現了1GB THP,但還沒有merge到linux kernel主流版本中)
THP支援swap,並在需要時先將大頁拆分成小頁以便swap。此外,THP會盡可能分配大頁,並在無法分配大頁時falllback到小頁分配,整個過程完全透明,使用者友好。hugetlb不支援swap。
hugetlb能夠保證保留的大頁僅用於hugepage使用,這種固定分配方式在不同場景下具有不同的優劣勢,需要結合具體使用情況分析。
THP需要守護程序進行大頁管理,但其開銷很小,對效能影響微乎其微。hugetlb不需要守護程序。
參考連結
Allocating hugepages to a specific numa node on boot (redhat.com)
linux - using libhugetlbfs to allocate pages - Stack Overflow
How to check Transparent HugePage usage per process in Linux with examples (golinuxcloud.com)
5.2. Huge Pages and Transparent Huge Pages Red Hat Enterprise Linux 6 | Red Hat Customer Portal
How to allocate "huge" pages for C++ application on Linux - Stack Overflow