5

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

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

4

2 回答 2

4

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

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

我编写了一个名为 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

UNAVAIL列表示没有可用的映射信息 - 通常是因为该页面从未被访问过,因此根本没有任何页面支持。您可以看到,对于这些“大”分配,在分配之后只映射了一个页面,因为我们没有触及内存。

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

这个库不是生产就绪的,所以不要将它用于任何关键的事情(例如,一些失败只是调用exit())。欢迎投稿。


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

于 2017-12-14T22:42:43.110 回答
-1

传统的大页面和透明大页面 (THP) 之间存在差异。在 THP 的情况下,应用程序可以在没有任何开发人员支持(mmap、shmget 等)或系统管理员干预的情况下使用大页面。

在代码中,恐怕可能没有直接的方法来检查这一点。但是,如果您知道 sizeof() 分配的数据结构或缓冲区,则值得使用以下命令 grepping 并检查系统上的 THP 使用情况。在运行您的应用程序时,这种使用应该会增加:

# grep AnonHugePages /proc/meminfo
AnonHugePages:   2648064 kB
于 2014-08-26T07:27:21.643 回答