1. 程式人生 > 其它 >Linux中hugepage的使用方法

Linux中hugepage的使用方法

Linux中hugepage的使用方法

Linux中使用hugepage有兩種方法,分別是

  • hugetlb
  • transparent huge page (THP)

其中,hugetlb基於顯式分配並保留的大頁,而THP按需將記憶體轉換成大頁,無需提前保留,提供更加靈活、對系統其他部分影響更小的大頁使用方式。

Hugetlb使用方法

分配大頁
  1. 預設size大頁

    echo N > /proc/sys/vm/nr_hugepages將試圖分配N個大頁,頁面大小是預設的(一般是2MB)。如果原來保留的頁面個數大於N,那麼將會釋放多出來的頁面。如果連續記憶體不夠將保留頁面數上升到N,則盡最大努力分配。

    cat /proc/sys/vm/nr_hugepages可以檢視保留頁面個數。

  2. 在指定的NUMA結點試圖分配N個指定頁面大小的hugepage,修改或讀取檔案:/sys/devices/system/node/node<node_id>/hugepages/hugepages-<page_size>/nr_hugepages

  3. NUMA結點無關的指定頁面大小的hugepage:/sys/kernel/mm/hugepages/hugepages-1048576kB/。如果直接寫該檔案來提升頁面個數,將重複依次在各個NUMA結點試圖分配一個頁面(node0, node1, node2, node3, ..., node0, node1, node2, node3, ...)直到滿足或不可進一步分配,例如:

    1. 在每個node資源充足的情況下,將均勻分配頁面到各個node。
    2. 若只有一個node可以分配大頁,則大頁全部分配到該node上。
    3. 若所有node可分配大頁的記憶體總量之和仍不能滿足N,則每個node盡最大努力分配大頁。
使用大頁

這裡僅介紹mmap使用大頁的方法。

在mmap的flag中新增MAP_HUGETLB和<MAP_HUGE>。其中,<MAP_HUGE>為((N & MAP_HUGE_MASK) << MAP_HUGE_SHIFT)MAP_HUGE_MASK == 0x3f == 0b111111MAP_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/enabledmadvisealways即可開啟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)

How to enable or disable transparent (THP) and explicit (nr_hugepages) hugepage and check the status in Linux with examples (explained in detail) - GoLinuxHub

5.2. Huge Pages and Transparent Huge Pages Red Hat Enterprise Linux 6 | Red Hat Customer Portal

How to use, monitor, and disable transparent hugepages in Red Hat Enterprise Linux 6 and 7? - Red Hat Customer Portal

How to allocate "huge" pages for C++ application on Linux - Stack Overflow

Large pages and hotplug memory - IBM Documentation