确定通过 malloc() 进行的分配是否由大页面支持

Bee*_*ope 5 c++ linux performance x86 huge-pages

我非常了解透明大页面的工作原理,并且任何分配(例如由 执行的分配)都malloc可以由大页面来满足。

我想知道的是,在分配后是否可以进行任何检查(可能是启发式的)以确定内存是否由大页面支持。

Bee*_*ope 5

您可以通过查找文件中的“pfn”(页面框架编号)来确定任何页面的确切状态,包括它是否由透明(或不透明)大页面支持/proc/kpageflags/proc/$PID/pagemap您可以通过读取进程的文件来获取页面的 pfn ,该文件按虚拟地址进行索引。

不幸的是,只有 root 用户才能访问1pfn中的值和整个文件。不过,如果您至少可以在您感兴趣的测试或基准测试场景中以 root 身份运行流程,那么这效果很好。pagemap/proc/kpageflags

我编写了一个名为 page-info 的小型库,它为您进行相关解析。给它一个内存范围,它会返回每个页面的信息,包括它是否存在于内存中、是否由大页面支持等。

例如,运行包含的测试进程会sudo ./page-info-test THP给出以下输出:

PAGE_SIZE = 4096, PID = 18868
       size memset       FLAG     SET   UNSET UNAVAIL
   0.25 MiB BEFORE        THP       0       1      64
   0.25 MiB AFTER         THP       0      65       0
   0.50 MiB BEFORE        THP       0       1     128
   0.50 MiB AFTER         THP       0     129       0
   1.00 MiB BEFORE        THP       0       1     256
   1.00 MiB AFTER         THP       0     257       0
   2.00 MiB BEFORE        THP       0       1     512
   2.00 MiB AFTER         THP       0     513       0
   4.00 MiB BEFORE        THP       0       1    1024
   4.00 MiB AFTER         THP     512     513       0
   8.00 MiB BEFORE        THP       0       1    2048
   8.00 MiB AFTER         THP    1536     513       0
  16.00 MiB BEFORE        THP       0       1    4096
  16.00 MiB AFTER         THP    3584     513       0
  32.00 MiB BEFORE        THP       0       1    8192
  32.00 MiB AFTER         THP    7680     513       0
  64.00 MiB BEFORE        THP       0       1   16384
  64.00 MiB AFTER         THP   15872     513       0
 128.00 MiB BEFORE        THP       0       1   32768
 128.00 MiB AFTER         THP   32256     513       0
 256.00 MiB BEFORE        THP       0       1   65536
 256.00 MiB AFTER         THP   65024     513       0
 512.00 MiB BEFORE        THP       0       1  131072
 512.00 MiB AFTER         THP  124416    6657       0
1024.00 MiB BEFORE        THP       0       1  262144
1024.00 MiB AFTER         THP       0  262145       0
DONE
Run Code Online (Sandbox Code Playgroud)

UNAVAIL列意味着没有可用的映射信息 - 通常是因为该页面从未被访问过,因此尚未得到任何页面的支持。您可以看到,对于这些“较大”的分配,分配后仅映射一个页面,因为我们尚未触及内存。

调用整个分配后,行是相同的信息,这导致所有页面都被物理分配AFTERmemset()在这里我们可以看到,在我们达到 4 MiB 的分配之前,没有任何分配是由透明大页支持的,此时每个分配的大部分都由 THP 支持,除了 513 页(结果位于分配区域的边缘) )。在 512 MiB 时,系统开始耗尽可用的大页面,但仍然满足大部分分配,但在 1024 MiB 时,整个分配都满足小页面。

该库还没有准备好用于生产,所以不要将它用于任何关键的事情(例如,某些故障只是调用exit())。欢迎贡献。


1大约从内核 4.0 开始,在此之前 pfn 可供非 root 用户进程访问。从 4.0 到 4.1 左右,整个文件pagemap对非 root 进程都是禁止的,但从那时起,该文件再次可用,但 pfn 被屏蔽(它将始终显示为零)。

  • 我写了一个带有独立代码的教程来检查这一点:https://mazzo.li/posts/check-huge-page.html (2认同)