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 == 26N为大页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

原文地址:https://www.cnblogs.com/fty1777/p/15571139.html