对大页面使用 mmap 和 madvise

Using mmap and madvise for huge pages

我想在 Linux 机器使用的大页面上分配内存。我看到有两种方法可以做到这一点,使用 mmapmadvise

也就是说,在 mmap 调用中使用 MAP_HUGETLB 标志 -

base_ptr_ = mmap(NULL, memory_size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);

并且 MADV_HUGEPAGE 标志与 madvise 调用 -

madvise(base_ptr_, memory_size_, MADV_HUGEPAGE);

谁能解释一下两者的区别?

这两个函数执行不同的操作,这在您的上下文中可能重要也可能不重要:

  • madvise 为传递给它的区域对应的所有内存映射设置一个标志,告诉 khugepaged 内核线程它可以考虑将所述映射提升为巨大页。这只有在启用透明大页面支持时才有效(透明大页面支持的状态在 /sys/kernel/mm/transparent_hugepage/enabled 下可用),大多数发行版都是这种情况,但在嵌入式系统上可能会被禁用。

  • mmap 实际上会继续并保留内核内部 hugetlbfs 挂载的页面,其状态可以在 /sys/kernel/mm/hugepages 下看到。相关页面需要在 mmap 被调用时可用(参见 /proc/meminfo 中的 HugePages_Free),否则 mmap 将失败。

这两种机制在内核树中有自己的doc文件:hugetlbpage.txt and transhuge.txt